1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "tools/rc.h" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "vcl/event.hxx" 34*cdf0e10cSrcweir #include "vcl/decoview.hxx" 35*cdf0e10cSrcweir #include "vcl/spin.h" 36*cdf0e10cSrcweir #include "vcl/spinfld.hxx" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include "controldata.hxx" 39*cdf0e10cSrcweir #include "svdata.hxx" 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir // ======================================================================= 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir void ImplGetSpinbuttonValue( Window *pWin, const Rectangle& rUpperRect, 44*cdf0e10cSrcweir const Rectangle& rLowerRect, 45*cdf0e10cSrcweir sal_Bool bUpperIn, sal_Bool bLowerIn, 46*cdf0e10cSrcweir sal_Bool bUpperEnabled, sal_Bool bLowerEnabled, sal_Bool bHorz, 47*cdf0e10cSrcweir SpinbuttonValue& rValue ) 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir // convert spinbutton data to a SpinbuttonValue structure for native painting 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir rValue.maUpperRect = rUpperRect; 52*cdf0e10cSrcweir rValue.maLowerRect = rLowerRect; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir Point aPointerPos = pWin->GetPointerPosPixel(); 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir ControlState nState = CTRL_STATE_ENABLED; 57*cdf0e10cSrcweir if ( bUpperIn ) 58*cdf0e10cSrcweir nState |= CTRL_STATE_PRESSED; 59*cdf0e10cSrcweir if ( !pWin->IsEnabled() || !bUpperEnabled ) 60*cdf0e10cSrcweir nState &= ~CTRL_STATE_ENABLED; 61*cdf0e10cSrcweir if ( pWin->HasFocus() ) 62*cdf0e10cSrcweir nState |= CTRL_STATE_FOCUSED; 63*cdf0e10cSrcweir if( pWin->IsMouseOver() && rUpperRect.IsInside( aPointerPos ) ) 64*cdf0e10cSrcweir nState |= CTRL_STATE_ROLLOVER; 65*cdf0e10cSrcweir rValue.mnUpperState = nState; 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir nState = CTRL_STATE_ENABLED; 68*cdf0e10cSrcweir if ( bLowerIn ) 69*cdf0e10cSrcweir nState |= CTRL_STATE_PRESSED; 70*cdf0e10cSrcweir if ( !pWin->IsEnabled() || !bLowerEnabled ) 71*cdf0e10cSrcweir nState &= ~CTRL_STATE_ENABLED; 72*cdf0e10cSrcweir if ( pWin->HasFocus() ) 73*cdf0e10cSrcweir nState |= CTRL_STATE_FOCUSED; 74*cdf0e10cSrcweir // for overlapping spins: highlight only one 75*cdf0e10cSrcweir if( pWin->IsMouseOver() && rLowerRect.IsInside( aPointerPos ) && 76*cdf0e10cSrcweir !rUpperRect.IsInside( aPointerPos ) ) 77*cdf0e10cSrcweir nState |= CTRL_STATE_ROLLOVER; 78*cdf0e10cSrcweir rValue.mnLowerState = nState; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir rValue.mnUpperPart = bHorz ? PART_BUTTON_LEFT : PART_BUTTON_UP; 81*cdf0e10cSrcweir rValue.mnLowerPart = bHorz ? PART_BUTTON_RIGHT : PART_BUTTON_DOWN; 82*cdf0e10cSrcweir } 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir sal_Bool ImplDrawNativeSpinfield( Window *pWin, const SpinbuttonValue& rSpinbuttonValue ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir sal_Bool bNativeOK = sal_False; 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir if( pWin->IsNativeControlSupported(CTRL_SPINBOX, PART_ENTIRE_CONTROL) && 90*cdf0e10cSrcweir // there is just no useful native support for spinfields with dropdown 91*cdf0e10cSrcweir !(pWin->GetStyle() & WB_DROPDOWN) ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir if( pWin->IsNativeControlSupported(CTRL_SPINBOX, rSpinbuttonValue.mnUpperPart) && 94*cdf0e10cSrcweir pWin->IsNativeControlSupported(CTRL_SPINBOX, rSpinbuttonValue.mnLowerPart) ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir // only paint the embedded spin buttons, all buttons are painted at once 97*cdf0e10cSrcweir bNativeOK = pWin->DrawNativeControl( CTRL_SPINBOX, PART_ALL_BUTTONS, Rectangle(), CTRL_STATE_ENABLED, 98*cdf0e10cSrcweir rSpinbuttonValue, rtl::OUString() ); 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir else 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir // paint the spinbox as a whole, use borderwindow to have proper clipping 103*cdf0e10cSrcweir Window *pBorder = pWin->GetWindow( WINDOW_BORDER ); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir // to not overwrite everything, set the button region as clipregion to the border window 106*cdf0e10cSrcweir Rectangle aClipRect( rSpinbuttonValue.maLowerRect ); 107*cdf0e10cSrcweir aClipRect.Union( rSpinbuttonValue.maUpperRect ); 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir // convert from screen space to borderwin space 110*cdf0e10cSrcweir aClipRect.SetPos( pBorder->ScreenToOutputPixel(pWin->OutputToScreenPixel(aClipRect.TopLeft())) ); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir Region oldRgn( pBorder->GetClipRegion() ); 113*cdf0e10cSrcweir pBorder->SetClipRegion( Region( aClipRect ) ); 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir Point aPt; 116*cdf0e10cSrcweir Size aSize( pBorder->GetOutputSizePixel() ); // the size of the border window, i.e., the whole control 117*cdf0e10cSrcweir Rectangle aBound, aContent; 118*cdf0e10cSrcweir Rectangle aNatRgn( aPt, aSize ); 119*cdf0e10cSrcweir if( ! ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize && 120*cdf0e10cSrcweir pBorder->GetNativeControlRegion( CTRL_SPINBOX, PART_ENTIRE_CONTROL, 121*cdf0e10cSrcweir aNatRgn, 0, rSpinbuttonValue, rtl::OUString(), aBound, aContent) ) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir aSize = aContent.GetSize(); 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir Rectangle aRgn( aPt, aSize ); 127*cdf0e10cSrcweir bNativeOK = pBorder->DrawNativeControl( CTRL_SPINBOX, PART_ENTIRE_CONTROL, aRgn, CTRL_STATE_ENABLED, 128*cdf0e10cSrcweir rSpinbuttonValue, rtl::OUString() ); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir pBorder->SetClipRegion( oldRgn ); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir return bNativeOK; 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir sal_Bool ImplDrawNativeSpinbuttons( Window *pWin, const SpinbuttonValue& rSpinbuttonValue ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir sal_Bool bNativeOK = sal_False; 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir if( pWin->IsNativeControlSupported(CTRL_SPINBUTTONS, PART_ENTIRE_CONTROL) ) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir // only paint the standalone spin buttons, all buttons are painted at once 143*cdf0e10cSrcweir bNativeOK = pWin->DrawNativeControl( CTRL_SPINBUTTONS, PART_ALL_BUTTONS, Rectangle(), CTRL_STATE_ENABLED, 144*cdf0e10cSrcweir rSpinbuttonValue, rtl::OUString() ); 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir return bNativeOK; 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir void ImplDrawSpinButton( OutputDevice* pOutDev, 150*cdf0e10cSrcweir const Rectangle& rUpperRect, 151*cdf0e10cSrcweir const Rectangle& rLowerRect, 152*cdf0e10cSrcweir sal_Bool bUpperIn, sal_Bool bLowerIn, 153*cdf0e10cSrcweir sal_Bool bUpperEnabled, sal_Bool bLowerEnabled, sal_Bool bHorz, sal_Bool bMirrorHorz ) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir DecorationView aDecoView( pOutDev ); 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir sal_uInt16 nStyle = BUTTON_DRAW_NOLEFTLIGHTBORDER; 158*cdf0e10cSrcweir sal_uInt16 nSymStyle = 0; 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir SymbolType eType1, eType2; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings(); 163*cdf0e10cSrcweir if ( rStyleSettings.GetOptions() & STYLE_OPTION_SPINARROW ) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir // arrows are only use in OS/2 look 166*cdf0e10cSrcweir if ( bHorz ) 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir eType1 = bMirrorHorz ? SYMBOL_ARROW_RIGHT : SYMBOL_ARROW_LEFT; 169*cdf0e10cSrcweir eType2 = bMirrorHorz ? SYMBOL_ARROW_LEFT : SYMBOL_ARROW_RIGHT; 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir else 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir eType1 = SYMBOL_ARROW_UP; 174*cdf0e10cSrcweir eType2 = SYMBOL_ARROW_DOWN; 175*cdf0e10cSrcweir } 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir else 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir if ( bHorz ) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir eType1 = bMirrorHorz ? SYMBOL_SPIN_RIGHT : SYMBOL_SPIN_LEFT; 182*cdf0e10cSrcweir eType2 = bMirrorHorz ? SYMBOL_SPIN_LEFT : SYMBOL_SPIN_RIGHT; 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir else 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir eType1 = SYMBOL_SPIN_UP; 187*cdf0e10cSrcweir eType2 = SYMBOL_SPIN_DOWN; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir // Oberen/linken Button malen 192*cdf0e10cSrcweir sal_uInt16 nTempStyle = nStyle; 193*cdf0e10cSrcweir if ( bUpperIn ) 194*cdf0e10cSrcweir nTempStyle |= BUTTON_DRAW_PRESSED; 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir sal_Bool bNativeOK = sal_False; 197*cdf0e10cSrcweir Rectangle aUpRect; 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir if( pOutDev->GetOutDevType() == OUTDEV_WINDOW ) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir Window *pWin = (Window*) pOutDev; 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir // are we drawing standalone spin buttons or members of a spinfield ? 204*cdf0e10cSrcweir ControlType aControl = CTRL_SPINBUTTONS; 205*cdf0e10cSrcweir switch( pWin->GetType() ) 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir case WINDOW_EDIT: 208*cdf0e10cSrcweir case WINDOW_MULTILINEEDIT: 209*cdf0e10cSrcweir case WINDOW_PATTERNFIELD: 210*cdf0e10cSrcweir case WINDOW_METRICFIELD: 211*cdf0e10cSrcweir case WINDOW_CURRENCYFIELD: 212*cdf0e10cSrcweir case WINDOW_DATEFIELD: 213*cdf0e10cSrcweir case WINDOW_TIMEFIELD: 214*cdf0e10cSrcweir case WINDOW_LONGCURRENCYFIELD: 215*cdf0e10cSrcweir case WINDOW_NUMERICFIELD: 216*cdf0e10cSrcweir case WINDOW_SPINFIELD: 217*cdf0e10cSrcweir aControl = CTRL_SPINBOX; 218*cdf0e10cSrcweir break; 219*cdf0e10cSrcweir default: 220*cdf0e10cSrcweir aControl = CTRL_SPINBUTTONS; 221*cdf0e10cSrcweir break; 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir SpinbuttonValue aValue; 225*cdf0e10cSrcweir ImplGetSpinbuttonValue( pWin, rUpperRect, rLowerRect, 226*cdf0e10cSrcweir bUpperIn, bLowerIn, bUpperEnabled, bLowerEnabled, 227*cdf0e10cSrcweir bHorz, aValue ); 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir if( aControl == CTRL_SPINBOX ) 230*cdf0e10cSrcweir bNativeOK = ImplDrawNativeSpinfield( pWin, aValue ); 231*cdf0e10cSrcweir else if( aControl == CTRL_SPINBUTTONS ) 232*cdf0e10cSrcweir bNativeOK = ImplDrawNativeSpinbuttons( pWin, aValue ); 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir if( !bNativeOK ) 236*cdf0e10cSrcweir aUpRect = aDecoView.DrawButton( rUpperRect, nTempStyle ); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir // Unteren/rechten Button malen 239*cdf0e10cSrcweir if ( bLowerIn ) 240*cdf0e10cSrcweir nStyle |= BUTTON_DRAW_PRESSED; 241*cdf0e10cSrcweir Rectangle aLowRect; 242*cdf0e10cSrcweir if( !bNativeOK ) 243*cdf0e10cSrcweir aLowRect = aDecoView.DrawButton( rLowerRect, nStyle ); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir // Zusaetzliche Default-Kante wollen wir auch ausnutzen 246*cdf0e10cSrcweir aUpRect.Left()--; 247*cdf0e10cSrcweir aUpRect.Top()--; 248*cdf0e10cSrcweir aUpRect.Right()++; 249*cdf0e10cSrcweir aUpRect.Bottom()++; 250*cdf0e10cSrcweir aLowRect.Left()--; 251*cdf0e10cSrcweir aLowRect.Top()--; 252*cdf0e10cSrcweir aLowRect.Right()++; 253*cdf0e10cSrcweir aLowRect.Bottom()++; 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir // Wir malen auch in die Kante rein, damit man etwas erkennen kann, 256*cdf0e10cSrcweir // wenn das Rechteck zu klein ist 257*cdf0e10cSrcweir if ( aUpRect.GetHeight() < 4 ) 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir aUpRect.Right()++; 260*cdf0e10cSrcweir aUpRect.Bottom()++; 261*cdf0e10cSrcweir aLowRect.Right()++; 262*cdf0e10cSrcweir aLowRect.Bottom()++; 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir // Symbolgroesse berechnen 266*cdf0e10cSrcweir long nTempSize1 = aUpRect.GetWidth(); 267*cdf0e10cSrcweir long nTempSize2 = aLowRect.GetWidth(); 268*cdf0e10cSrcweir if ( Abs( nTempSize1-nTempSize2 ) == 1 ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir if ( nTempSize1 > nTempSize2 ) 271*cdf0e10cSrcweir aUpRect.Left()++; 272*cdf0e10cSrcweir else 273*cdf0e10cSrcweir aLowRect.Left()++; 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir nTempSize1 = aUpRect.GetHeight(); 276*cdf0e10cSrcweir nTempSize2 = aLowRect.GetHeight(); 277*cdf0e10cSrcweir if ( Abs( nTempSize1-nTempSize2 ) == 1 ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir if ( nTempSize1 > nTempSize2 ) 280*cdf0e10cSrcweir aUpRect.Top()++; 281*cdf0e10cSrcweir else 282*cdf0e10cSrcweir aLowRect.Top()++; 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir nTempStyle = nSymStyle; 286*cdf0e10cSrcweir if ( !bUpperEnabled ) 287*cdf0e10cSrcweir nTempStyle |= SYMBOL_DRAW_DISABLE; 288*cdf0e10cSrcweir if( !bNativeOK ) 289*cdf0e10cSrcweir aDecoView.DrawSymbol( aUpRect, eType1, rStyleSettings.GetButtonTextColor(), nTempStyle ); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if ( !bLowerEnabled ) 292*cdf0e10cSrcweir nSymStyle |= SYMBOL_DRAW_DISABLE; 293*cdf0e10cSrcweir if( !bNativeOK ) 294*cdf0e10cSrcweir aDecoView.DrawSymbol( aLowRect, eType2, rStyleSettings.GetButtonTextColor(), nSymStyle ); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir // ======================================================================= 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir void SpinField::ImplInitSpinFieldData() 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir mpEdit = NULL; 302*cdf0e10cSrcweir mbSpin = sal_False; 303*cdf0e10cSrcweir mbRepeat = sal_False; 304*cdf0e10cSrcweir mbUpperIn = sal_False; 305*cdf0e10cSrcweir mbLowerIn = sal_False; 306*cdf0e10cSrcweir mbInitialUp = sal_False; 307*cdf0e10cSrcweir mbInitialDown = sal_False; 308*cdf0e10cSrcweir mbNoSelect = sal_False; 309*cdf0e10cSrcweir mbInDropDown = sal_False; 310*cdf0e10cSrcweir } 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir // -------------------------------------------------------------------- 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir void SpinField::ImplInit( Window* pParent, WinBits nWinStyle ) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir Edit::ImplInit( pParent, nWinStyle ); 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir if ( nWinStyle & (WB_SPIN|WB_DROPDOWN) ) 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir mbSpin = sal_True; 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir // Some themes want external spin buttons, therefore the main 323*cdf0e10cSrcweir // spinfield should not overdraw the border between its encapsulated 324*cdf0e10cSrcweir // edit field and the spin buttons 325*cdf0e10cSrcweir if ( (nWinStyle & WB_SPIN) && ImplUseNativeBorder( nWinStyle ) ) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir SetBackground(); 328*cdf0e10cSrcweir mpEdit = new Edit( this, WB_NOBORDER ); 329*cdf0e10cSrcweir mpEdit->SetBackground(); 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir else 332*cdf0e10cSrcweir mpEdit = new Edit( this, WB_NOBORDER ); 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir mpEdit->EnableRTL( sal_False ); 335*cdf0e10cSrcweir mpEdit->SetPosPixel( Point() ); 336*cdf0e10cSrcweir mpEdit->Show(); 337*cdf0e10cSrcweir SetSubEdit( mpEdit ); 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir maRepeatTimer.SetTimeoutHdl( LINK( this, SpinField, ImplTimeout ) ); 340*cdf0e10cSrcweir maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() ); 341*cdf0e10cSrcweir if ( nWinStyle & WB_REPEAT ) 342*cdf0e10cSrcweir mbRepeat = sal_True; 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir SetCompoundControl( sal_True ); 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir // -------------------------------------------------------------------- 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir SpinField::SpinField( WindowType nTyp ) : 351*cdf0e10cSrcweir Edit( nTyp ) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir ImplInitSpinFieldData(); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir // -------------------------------------------------------------------- 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir SpinField::SpinField( Window* pParent, WinBits nWinStyle ) : 359*cdf0e10cSrcweir Edit( WINDOW_SPINFIELD ) 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir ImplInitSpinFieldData(); 362*cdf0e10cSrcweir ImplInit( pParent, nWinStyle ); 363*cdf0e10cSrcweir } 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir // -------------------------------------------------------------------- 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir SpinField::SpinField( Window* pParent, const ResId& rResId ) : 368*cdf0e10cSrcweir Edit( WINDOW_SPINFIELD ) 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir ImplInitSpinFieldData(); 371*cdf0e10cSrcweir rResId.SetRT( RSC_SPINFIELD ); 372*cdf0e10cSrcweir WinBits nStyle = ImplInitRes( rResId ); 373*cdf0e10cSrcweir ImplInit( pParent, nStyle ); 374*cdf0e10cSrcweir ImplLoadRes( rResId ); 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir if ( !(nStyle & WB_HIDE) ) 377*cdf0e10cSrcweir Show(); 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir // -------------------------------------------------------------------- 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir SpinField::~SpinField() 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir delete mpEdit; 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir // -------------------------------------------------------------------- 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir void SpinField::Up() 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir ImplCallEventListenersAndHandler( VCLEVENT_SPINFIELD_UP, maUpHdlLink, this ); 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir // -------------------------------------------------------------------- 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir void SpinField::Down() 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir ImplCallEventListenersAndHandler( VCLEVENT_SPINFIELD_DOWN, maDownHdlLink, this ); 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir // -------------------------------------------------------------------- 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir void SpinField::First() 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir ImplCallEventListenersAndHandler( VCLEVENT_SPINFIELD_FIRST, maFirstHdlLink, this ); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir // -------------------------------------------------------------------- 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir void SpinField::Last() 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir ImplCallEventListenersAndHandler( VCLEVENT_SPINFIELD_LAST, maLastHdlLink, this ); 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir // -------------------------------------------------------------------- 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir void SpinField::MouseButtonDown( const MouseEvent& rMEvt ) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir if ( !HasFocus() && ( !mpEdit || !mpEdit->HasFocus() ) ) 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir mbNoSelect = sal_True; 422*cdf0e10cSrcweir GrabFocus(); 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir if ( !IsReadOnly() ) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir if ( maUpperRect.IsInside( rMEvt.GetPosPixel() ) ) 428*cdf0e10cSrcweir { 429*cdf0e10cSrcweir mbUpperIn = sal_True; 430*cdf0e10cSrcweir mbInitialUp = sal_True; 431*cdf0e10cSrcweir Invalidate( maUpperRect ); 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir else if ( maLowerRect.IsInside( rMEvt.GetPosPixel() ) ) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir mbLowerIn = sal_True; 436*cdf0e10cSrcweir mbInitialDown = sal_True; 437*cdf0e10cSrcweir Invalidate( maLowerRect ); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir else if ( maDropDownRect.IsInside( rMEvt.GetPosPixel() ) ) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir // Rechts daneben liegt der DropDownButton: 442*cdf0e10cSrcweir mbInDropDown = ShowDropDown( mbInDropDown ? sal_False : sal_True ); 443*cdf0e10cSrcweir Paint( Rectangle( Point(), GetOutputSizePixel() ) ); 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir if ( mbUpperIn || mbLowerIn ) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir Update(); 449*cdf0e10cSrcweir CaptureMouse(); 450*cdf0e10cSrcweir if ( mbRepeat ) 451*cdf0e10cSrcweir maRepeatTimer.Start(); 452*cdf0e10cSrcweir return; 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir Edit::MouseButtonDown( rMEvt ); 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir // -------------------------------------------------------------------- 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir void SpinField::MouseButtonUp( const MouseEvent& rMEvt ) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir ReleaseMouse(); 464*cdf0e10cSrcweir mbInitialUp = mbInitialDown = sal_False; 465*cdf0e10cSrcweir maRepeatTimer.Stop(); 466*cdf0e10cSrcweir maRepeatTimer.SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() ); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir if ( mbUpperIn ) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir mbUpperIn = sal_False; 471*cdf0e10cSrcweir Invalidate( maUpperRect ); 472*cdf0e10cSrcweir Update(); 473*cdf0e10cSrcweir Up(); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir else if ( mbLowerIn ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir mbLowerIn = sal_False; 478*cdf0e10cSrcweir Invalidate( maLowerRect ); 479*cdf0e10cSrcweir Update(); 480*cdf0e10cSrcweir Down(); 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir Edit::MouseButtonUp( rMEvt ); 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir // -------------------------------------------------------------------- 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir void SpinField::MouseMove( const MouseEvent& rMEvt ) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir if ( rMEvt.IsLeft() ) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir if ( mbInitialUp ) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir sal_Bool bNewUpperIn = maUpperRect.IsInside( rMEvt.GetPosPixel() ); 495*cdf0e10cSrcweir if ( bNewUpperIn != mbUpperIn ) 496*cdf0e10cSrcweir { 497*cdf0e10cSrcweir if ( bNewUpperIn ) 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir if ( mbRepeat ) 500*cdf0e10cSrcweir maRepeatTimer.Start(); 501*cdf0e10cSrcweir } 502*cdf0e10cSrcweir else 503*cdf0e10cSrcweir maRepeatTimer.Stop(); 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir mbUpperIn = bNewUpperIn; 506*cdf0e10cSrcweir Invalidate( maUpperRect ); 507*cdf0e10cSrcweir Update(); 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir else if ( mbInitialDown ) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir sal_Bool bNewLowerIn = maLowerRect.IsInside( rMEvt.GetPosPixel() ); 513*cdf0e10cSrcweir if ( bNewLowerIn != mbLowerIn ) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir if ( bNewLowerIn ) 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir if ( mbRepeat ) 518*cdf0e10cSrcweir maRepeatTimer.Start(); 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir else 521*cdf0e10cSrcweir maRepeatTimer.Stop(); 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir mbLowerIn = bNewLowerIn; 524*cdf0e10cSrcweir Invalidate( maLowerRect ); 525*cdf0e10cSrcweir Update(); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir Edit::MouseMove( rMEvt ); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir // -------------------------------------------------------------------- 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir long SpinField::Notify( NotifyEvent& rNEvt ) 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir long nDone = 0; 538*cdf0e10cSrcweir if( rNEvt.GetType() == EVENT_KEYINPUT ) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir const KeyEvent& rKEvt = *rNEvt.GetKeyEvent(); 541*cdf0e10cSrcweir if ( !IsReadOnly() ) 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier(); 544*cdf0e10cSrcweir switch ( rKEvt.GetKeyCode().GetCode() ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir case KEY_UP: 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir if ( !nMod ) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir Up(); 551*cdf0e10cSrcweir nDone = 1; 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir break; 555*cdf0e10cSrcweir case KEY_DOWN: 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir if ( !nMod ) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir Down(); 560*cdf0e10cSrcweir nDone = 1; 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir else if ( ( nMod == KEY_MOD2 ) && !mbInDropDown && ( GetStyle() & WB_DROPDOWN ) ) 563*cdf0e10cSrcweir { 564*cdf0e10cSrcweir mbInDropDown = ShowDropDown( sal_True ); 565*cdf0e10cSrcweir Paint( Rectangle( Point(), GetOutputSizePixel() ) ); 566*cdf0e10cSrcweir nDone = 1; 567*cdf0e10cSrcweir } 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir break; 570*cdf0e10cSrcweir case KEY_PAGEUP: 571*cdf0e10cSrcweir { 572*cdf0e10cSrcweir if ( !nMod ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir Last(); 575*cdf0e10cSrcweir nDone = 1; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir break; 579*cdf0e10cSrcweir case KEY_PAGEDOWN: 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir if ( !nMod ) 582*cdf0e10cSrcweir { 583*cdf0e10cSrcweir First(); 584*cdf0e10cSrcweir nDone = 1; 585*cdf0e10cSrcweir } 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir break; 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir if ( rNEvt.GetType() == EVENT_COMMAND ) 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir if ( ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) && !IsReadOnly() ) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir sal_uInt16 nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() ); 597*cdf0e10cSrcweir if ( ( nWheelBehavior == MOUSE_WHEEL_ALWAYS ) 598*cdf0e10cSrcweir || ( ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY ) 599*cdf0e10cSrcweir && HasChildPathFocus() 600*cdf0e10cSrcweir ) 601*cdf0e10cSrcweir ) 602*cdf0e10cSrcweir { 603*cdf0e10cSrcweir const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); 604*cdf0e10cSrcweir if ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir if ( pData->GetDelta() < 0L ) 607*cdf0e10cSrcweir Down(); 608*cdf0e10cSrcweir else 609*cdf0e10cSrcweir Up(); 610*cdf0e10cSrcweir nDone = 1; 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir else 614*cdf0e10cSrcweir nDone = 0; // don't eat this event, let the default handling happen (i.e. scroll the context) 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir return nDone ? nDone : Edit::Notify( rNEvt ); 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir // -------------------------------------------------------------------- 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir void SpinField::Command( const CommandEvent& rCEvt ) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir Edit::Command( rCEvt ); 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir // -------------------------------------------------------------------- 629*cdf0e10cSrcweir 630*cdf0e10cSrcweir void SpinField::FillLayoutData() const 631*cdf0e10cSrcweir { 632*cdf0e10cSrcweir if( mbSpin ) 633*cdf0e10cSrcweir { 634*cdf0e10cSrcweir mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 635*cdf0e10cSrcweir AppendLayoutData( *GetSubEdit() ); 636*cdf0e10cSrcweir GetSubEdit()->SetLayoutDataParent( this ); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir else 639*cdf0e10cSrcweir Edit::FillLayoutData(); 640*cdf0e10cSrcweir } 641*cdf0e10cSrcweir 642*cdf0e10cSrcweir // -------------------------------------------------------------------- 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir void SpinField::Paint( const Rectangle& rRect ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir if ( mbSpin ) 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir sal_Bool bEnable = IsEnabled(); 649*cdf0e10cSrcweir ImplDrawSpinButton( this, maUpperRect, maLowerRect, 650*cdf0e10cSrcweir mbUpperIn, mbLowerIn, bEnable, bEnable ); 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir DecorationView aView( this ); 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir sal_uInt16 nStyle = BUTTON_DRAW_NOLIGHTBORDER; 658*cdf0e10cSrcweir if ( mbInDropDown ) 659*cdf0e10cSrcweir nStyle |= BUTTON_DRAW_PRESSED; 660*cdf0e10cSrcweir Rectangle aInnerRect = aView.DrawButton( maDropDownRect, nStyle ); 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir SymbolType eSymbol = SYMBOL_SPIN_DOWN; 663*cdf0e10cSrcweir if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN ) 664*cdf0e10cSrcweir eSymbol = SYMBOL_SPIN_UPDOWN; 665*cdf0e10cSrcweir 666*cdf0e10cSrcweir nStyle = IsEnabled() ? 0 : SYMBOL_DRAW_DISABLE; 667*cdf0e10cSrcweir aView.DrawSymbol( aInnerRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle ); 668*cdf0e10cSrcweir } 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir Edit::Paint( rRect ); 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir // -------------------------------------------------------------------- 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir void SpinField::ImplCalcButtonAreas( OutputDevice* pDev, const Size& rOutSz, Rectangle& rDDArea, Rectangle& rSpinUpArea, Rectangle& rSpinDownArea ) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings(); 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir Size aSize = rOutSz; 680*cdf0e10cSrcweir Size aDropDownSize; 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir long nW = rStyleSettings.GetScrollBarSize(); 685*cdf0e10cSrcweir nW = GetDrawPixel( pDev, nW ); 686*cdf0e10cSrcweir aDropDownSize = Size( CalcZoom( nW ), aSize.Height() ); 687*cdf0e10cSrcweir aSize.Width() -= aDropDownSize.Width(); 688*cdf0e10cSrcweir rDDArea = Rectangle( Point( aSize.Width(), 0 ), aDropDownSize ); 689*cdf0e10cSrcweir rDDArea.Top()--; 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir else 692*cdf0e10cSrcweir rDDArea.SetEmpty(); 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir // Je nach Hoehe, die groessen Berechnen 695*cdf0e10cSrcweir if ( GetStyle() & WB_SPIN ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir long nBottom1 = aSize.Height()/2; 698*cdf0e10cSrcweir long nBottom2 = aSize.Height()-1; 699*cdf0e10cSrcweir long nTop2 = nBottom1; 700*cdf0e10cSrcweir long nTop1 = 0; 701*cdf0e10cSrcweir if ( !(aSize.Height() & 0x01) ) 702*cdf0e10cSrcweir nBottom1--; 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir sal_Bool bNativeRegionOK = sal_False; 705*cdf0e10cSrcweir Rectangle aContentUp, aContentDown; 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir if ( (pDev->GetOutDevType() == OUTDEV_WINDOW) && 708*cdf0e10cSrcweir // there is just no useful native support for spinfields with dropdown 709*cdf0e10cSrcweir ! (GetStyle() & WB_DROPDOWN) && 710*cdf0e10cSrcweir IsNativeControlSupported(CTRL_SPINBOX, PART_ENTIRE_CONTROL) ) 711*cdf0e10cSrcweir { 712*cdf0e10cSrcweir Window *pWin = (Window*) pDev; 713*cdf0e10cSrcweir Window *pBorder = pWin->GetWindow( WINDOW_BORDER ); 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir // get the system's spin button size 716*cdf0e10cSrcweir ImplControlValue aControlValue; 717*cdf0e10cSrcweir Rectangle aBound; 718*cdf0e10cSrcweir Point aPoint; 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir // use the full extent of the control 721*cdf0e10cSrcweir Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir bNativeRegionOK = 724*cdf0e10cSrcweir pWin->GetNativeControlRegion(CTRL_SPINBOX, PART_BUTTON_UP, 725*cdf0e10cSrcweir aArea, 0, aControlValue, rtl::OUString(), aBound, aContentUp) && 726*cdf0e10cSrcweir pWin->GetNativeControlRegion(CTRL_SPINBOX, PART_BUTTON_DOWN, 727*cdf0e10cSrcweir aArea, 0, aControlValue, rtl::OUString(), aBound, aContentDown); 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir if( bNativeRegionOK ) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir // convert back from border space to local coordinates 732*cdf0e10cSrcweir aPoint = pBorder->ScreenToOutputPixel( pWin->OutputToScreenPixel( aPoint ) ); 733*cdf0e10cSrcweir aContentUp.Move(-aPoint.X(), -aPoint.Y()); 734*cdf0e10cSrcweir aContentDown.Move(-aPoint.X(), -aPoint.Y()); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir if( bNativeRegionOK ) 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir rSpinUpArea = aContentUp; 741*cdf0e10cSrcweir rSpinDownArea = aContentDown; 742*cdf0e10cSrcweir } 743*cdf0e10cSrcweir else 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir aSize.Width() -= CalcZoom( GetDrawPixel( pDev, rStyleSettings.GetSpinSize() ) ); 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir rSpinUpArea = Rectangle( aSize.Width(), nTop1, rOutSz.Width()-aDropDownSize.Width()-1, nBottom1 ); 748*cdf0e10cSrcweir rSpinDownArea = Rectangle( rSpinUpArea.Left(), nTop2, rSpinUpArea.Right(), nBottom2 ); 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir } 751*cdf0e10cSrcweir else 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir rSpinUpArea.SetEmpty(); 754*cdf0e10cSrcweir rSpinDownArea.SetEmpty(); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir } 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir // -------------------------------------------------------------------- 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir void SpinField::Resize() 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir if ( mbSpin ) 763*cdf0e10cSrcweir { 764*cdf0e10cSrcweir Control::Resize(); 765*cdf0e10cSrcweir Size aSize = GetOutputSizePixel(); 766*cdf0e10cSrcweir bool bSubEditPositioned = false; 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir if ( GetStyle() & (WB_SPIN|WB_DROPDOWN) ) 769*cdf0e10cSrcweir { 770*cdf0e10cSrcweir ImplCalcButtonAreas( this, aSize, maDropDownRect, maUpperRect, maLowerRect ); 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir ImplControlValue aControlValue; 773*cdf0e10cSrcweir Point aPoint; 774*cdf0e10cSrcweir Rectangle aContent, aBound; 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir // use the full extent of the control 777*cdf0e10cSrcweir Window *pBorder = GetWindow( WINDOW_BORDER ); 778*cdf0e10cSrcweir Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir // adjust position and size of the edit field 781*cdf0e10cSrcweir if ( GetNativeControlRegion(CTRL_SPINBOX, PART_SUB_EDIT, 782*cdf0e10cSrcweir aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir // convert back from border space to local coordinates 785*cdf0e10cSrcweir aPoint = pBorder->ScreenToOutputPixel( OutputToScreenPixel( aPoint ) ); 786*cdf0e10cSrcweir aContent.Move(-aPoint.X(), -aPoint.Y()); 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir // use the themes drop down size 789*cdf0e10cSrcweir mpEdit->SetPosPixel( aContent.TopLeft() ); 790*cdf0e10cSrcweir bSubEditPositioned = true; 791*cdf0e10cSrcweir aSize = aContent.GetSize(); 792*cdf0e10cSrcweir } 793*cdf0e10cSrcweir else 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir if ( maUpperRect.IsEmpty() ) 796*cdf0e10cSrcweir { 797*cdf0e10cSrcweir DBG_ASSERT( !maDropDownRect.IsEmpty(), "SpinField::Resize: SPIN && DROPDOWN, but all empty rects?" ); 798*cdf0e10cSrcweir aSize.Width() = maDropDownRect.Left(); 799*cdf0e10cSrcweir } 800*cdf0e10cSrcweir else 801*cdf0e10cSrcweir aSize.Width() = maUpperRect.Left(); 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir if( ! bSubEditPositioned ) 806*cdf0e10cSrcweir { 807*cdf0e10cSrcweir // this moves our sub edit if RTL gets switched 808*cdf0e10cSrcweir mpEdit->SetPosPixel( Point() ); 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir mpEdit->SetSizePixel( aSize ); 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir if ( GetStyle() & WB_SPIN ) 813*cdf0e10cSrcweir Invalidate( Rectangle( maUpperRect.TopLeft(), maLowerRect.BottomRight() ) ); 814*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 815*cdf0e10cSrcweir Invalidate( maDropDownRect ); 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir // ----------------------------------------------------------------------- 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir void SpinField::StateChanged( StateChangedType nType ) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir Edit::StateChanged( nType ); 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir if ( nType == STATE_CHANGE_ENABLE ) 826*cdf0e10cSrcweir { 827*cdf0e10cSrcweir if ( mbSpin || ( GetStyle() & WB_DROPDOWN ) ) 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir mpEdit->Enable( IsEnabled() ); 830*cdf0e10cSrcweir 831*cdf0e10cSrcweir if ( mbSpin ) 832*cdf0e10cSrcweir { 833*cdf0e10cSrcweir Invalidate( maLowerRect ); 834*cdf0e10cSrcweir Invalidate( maUpperRect ); 835*cdf0e10cSrcweir } 836*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 837*cdf0e10cSrcweir Invalidate( maDropDownRect ); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir } 840*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_STYLE ) 841*cdf0e10cSrcweir { 842*cdf0e10cSrcweir if ( GetStyle() & WB_REPEAT ) 843*cdf0e10cSrcweir mbRepeat = sal_True; 844*cdf0e10cSrcweir else 845*cdf0e10cSrcweir mbRepeat = sal_False; 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_ZOOM ) 848*cdf0e10cSrcweir { 849*cdf0e10cSrcweir Resize(); 850*cdf0e10cSrcweir if ( mpEdit ) 851*cdf0e10cSrcweir mpEdit->SetZoom( GetZoom() ); 852*cdf0e10cSrcweir Invalidate(); 853*cdf0e10cSrcweir } 854*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFONT ) 855*cdf0e10cSrcweir { 856*cdf0e10cSrcweir if ( mpEdit ) 857*cdf0e10cSrcweir mpEdit->SetControlFont( GetControlFont() ); 858*cdf0e10cSrcweir ImplInitSettings( sal_True, sal_False, sal_False ); 859*cdf0e10cSrcweir Invalidate(); 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir if ( mpEdit ) 864*cdf0e10cSrcweir mpEdit->SetControlForeground( GetControlForeground() ); 865*cdf0e10cSrcweir ImplInitSettings( sal_False, sal_True, sal_False ); 866*cdf0e10cSrcweir Invalidate(); 867*cdf0e10cSrcweir } 868*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir if ( mpEdit ) 871*cdf0e10cSrcweir mpEdit->SetControlBackground( GetControlBackground() ); 872*cdf0e10cSrcweir ImplInitSettings( sal_False, sal_False, sal_True ); 873*cdf0e10cSrcweir Invalidate(); 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir else if( nType == STATE_CHANGE_MIRRORING ) 876*cdf0e10cSrcweir { 877*cdf0e10cSrcweir if( mpEdit ) 878*cdf0e10cSrcweir mpEdit->StateChanged( STATE_CHANGE_MIRRORING ); 879*cdf0e10cSrcweir Resize(); 880*cdf0e10cSrcweir } 881*cdf0e10cSrcweir } 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir // ----------------------------------------------------------------------- 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir void SpinField::DataChanged( const DataChangedEvent& rDCEvt ) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir Edit::DataChanged( rDCEvt ); 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 890*cdf0e10cSrcweir (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 891*cdf0e10cSrcweir { 892*cdf0e10cSrcweir Resize(); 893*cdf0e10cSrcweir Invalidate(); 894*cdf0e10cSrcweir } 895*cdf0e10cSrcweir } 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir // ----------------------------------------------------------------------- 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir Rectangle* SpinField::ImplFindPartRect( const Point& rPt ) 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir if( maUpperRect.IsInside( rPt ) ) 902*cdf0e10cSrcweir return &maUpperRect; 903*cdf0e10cSrcweir else if( maLowerRect.IsInside( rPt ) ) 904*cdf0e10cSrcweir return &maLowerRect; 905*cdf0e10cSrcweir else 906*cdf0e10cSrcweir return NULL; 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir long SpinField::PreNotify( NotifyEvent& rNEvt ) 910*cdf0e10cSrcweir { 911*cdf0e10cSrcweir long nDone = 0; 912*cdf0e10cSrcweir const MouseEvent* pMouseEvt = NULL; 913*cdf0e10cSrcweir 914*cdf0e10cSrcweir if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 915*cdf0e10cSrcweir { 916*cdf0e10cSrcweir if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() ) 917*cdf0e10cSrcweir { 918*cdf0e10cSrcweir // trigger redraw if mouse over state has changed 919*cdf0e10cSrcweir if( IsNativeControlSupported(CTRL_SPINBOX, PART_ENTIRE_CONTROL) || 920*cdf0e10cSrcweir IsNativeControlSupported(CTRL_SPINBOX, PART_ALL_BUTTONS) ) 921*cdf0e10cSrcweir { 922*cdf0e10cSrcweir Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() ); 923*cdf0e10cSrcweir Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() ); 924*cdf0e10cSrcweir if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) ) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir // FIXME: this is currently only on aqua 927*cdf0e10cSrcweir // check for other platforms that need similar handling 928*cdf0e10cSrcweir if( ImplGetSVData()->maNWFData.mbNoFocusRects && 929*cdf0e10cSrcweir IsNativeWidgetEnabled() && 930*cdf0e10cSrcweir IsNativeControlSupported( CTRL_EDITBOX, PART_ENTIRE_CONTROL ) ) 931*cdf0e10cSrcweir { 932*cdf0e10cSrcweir ImplInvalidateOutermostBorder( this ); 933*cdf0e10cSrcweir } 934*cdf0e10cSrcweir else 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir // paint directly 937*cdf0e10cSrcweir Region aRgn( GetActiveClipRegion() ); 938*cdf0e10cSrcweir if( pLastRect ) 939*cdf0e10cSrcweir { 940*cdf0e10cSrcweir SetClipRegion( *pLastRect ); 941*cdf0e10cSrcweir Paint( *pLastRect ); 942*cdf0e10cSrcweir SetClipRegion( aRgn ); 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir if( pRect ) 945*cdf0e10cSrcweir { 946*cdf0e10cSrcweir SetClipRegion( *pRect ); 947*cdf0e10cSrcweir Paint( *pRect ); 948*cdf0e10cSrcweir SetClipRegion( aRgn ); 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir } 951*cdf0e10cSrcweir } 952*cdf0e10cSrcweir } 953*cdf0e10cSrcweir } 954*cdf0e10cSrcweir } 955*cdf0e10cSrcweir 956*cdf0e10cSrcweir return nDone ? nDone : Edit::PreNotify(rNEvt); 957*cdf0e10cSrcweir } 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir // ----------------------------------------------------------------------- 960*cdf0e10cSrcweir 961*cdf0e10cSrcweir void SpinField::EndDropDown() 962*cdf0e10cSrcweir { 963*cdf0e10cSrcweir mbInDropDown = sal_False; 964*cdf0e10cSrcweir Paint( Rectangle( Point(), GetOutputSizePixel() ) ); 965*cdf0e10cSrcweir } 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir // ----------------------------------------------------------------------- 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir sal_Bool SpinField::ShowDropDown( sal_Bool ) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir return sal_False; 972*cdf0e10cSrcweir } 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir // ----------------------------------------------------------------------- 975*cdf0e10cSrcweir 976*cdf0e10cSrcweir Size SpinField::CalcMinimumSize() const 977*cdf0e10cSrcweir { 978*cdf0e10cSrcweir Size aSz = Edit::CalcMinimumSize(); 979*cdf0e10cSrcweir 980*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 981*cdf0e10cSrcweir aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); 982*cdf0e10cSrcweir if ( GetStyle() & WB_SPIN ) 983*cdf0e10cSrcweir aSz.Width() += maUpperRect.GetWidth(); 984*cdf0e10cSrcweir 985*cdf0e10cSrcweir return aSz; 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir // ----------------------------------------------------------------------- 989*cdf0e10cSrcweir 990*cdf0e10cSrcweir Size SpinField::GetOptimalSize(WindowSizeType eType) const 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir switch (eType) { 993*cdf0e10cSrcweir case WINDOWSIZE_MINIMUM: 994*cdf0e10cSrcweir return CalcMinimumSize(); 995*cdf0e10cSrcweir default: 996*cdf0e10cSrcweir return Edit::GetOptimalSize( eType ); 997*cdf0e10cSrcweir } 998*cdf0e10cSrcweir } 999*cdf0e10cSrcweir 1000*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1001*cdf0e10cSrcweir 1002*cdf0e10cSrcweir Size SpinField::CalcSize( sal_uInt16 nChars ) const 1003*cdf0e10cSrcweir { 1004*cdf0e10cSrcweir Size aSz = Edit::CalcSize( nChars ); 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 1007*cdf0e10cSrcweir aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); 1008*cdf0e10cSrcweir if ( GetStyle() & WB_SPIN ) 1009*cdf0e10cSrcweir aSz.Width() += GetSettings().GetStyleSettings().GetSpinSize(); 1010*cdf0e10cSrcweir 1011*cdf0e10cSrcweir return aSz; 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir // -------------------------------------------------------------------- 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir IMPL_LINK( SpinField, ImplTimeout, Timer*, pTimer ) 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir if ( pTimer->GetTimeout() == GetSettings().GetMouseSettings().GetButtonStartRepeat() ) 1019*cdf0e10cSrcweir { 1020*cdf0e10cSrcweir pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() ); 1021*cdf0e10cSrcweir pTimer->Start(); 1022*cdf0e10cSrcweir } 1023*cdf0e10cSrcweir else 1024*cdf0e10cSrcweir { 1025*cdf0e10cSrcweir if ( mbInitialUp ) 1026*cdf0e10cSrcweir Up(); 1027*cdf0e10cSrcweir else 1028*cdf0e10cSrcweir Down(); 1029*cdf0e10cSrcweir } 1030*cdf0e10cSrcweir return 0; 1031*cdf0e10cSrcweir } 1032*cdf0e10cSrcweir 1033*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir void SpinField::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir Edit::Draw( pDev, rPos, rSize, nFlags ); 1038*cdf0e10cSrcweir 1039*cdf0e10cSrcweir WinBits nFieldStyle = GetStyle(); 1040*cdf0e10cSrcweir if ( !(nFlags & WINDOW_DRAW_NOCONTROLS ) && ( nFieldStyle & (WB_SPIN|WB_DROPDOWN) ) ) 1041*cdf0e10cSrcweir { 1042*cdf0e10cSrcweir Point aPos = pDev->LogicToPixel( rPos ); 1043*cdf0e10cSrcweir Size aSize = pDev->LogicToPixel( rSize ); 1044*cdf0e10cSrcweir OutDevType eOutDevType = pDev->GetOutDevType(); 1045*cdf0e10cSrcweir AllSettings aOldSettings = pDev->GetSettings(); 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir pDev->Push(); 1048*cdf0e10cSrcweir pDev->SetMapMode(); 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir if ( eOutDevType == OUTDEV_PRINTER ) 1051*cdf0e10cSrcweir { 1052*cdf0e10cSrcweir StyleSettings aStyleSettings = aOldSettings.GetStyleSettings(); 1053*cdf0e10cSrcweir aStyleSettings.SetFaceColor( COL_LIGHTGRAY ); 1054*cdf0e10cSrcweir aStyleSettings.SetButtonTextColor( COL_BLACK ); 1055*cdf0e10cSrcweir AllSettings aSettings( aOldSettings ); 1056*cdf0e10cSrcweir aSettings.SetStyleSettings( aStyleSettings ); 1057*cdf0e10cSrcweir pDev->SetSettings( aSettings ); 1058*cdf0e10cSrcweir } 1059*cdf0e10cSrcweir 1060*cdf0e10cSrcweir Rectangle aDD, aUp, aDown; 1061*cdf0e10cSrcweir ImplCalcButtonAreas( pDev, aSize, aDD, aUp, aDown ); 1062*cdf0e10cSrcweir aDD.Move( aPos.X(), aPos.Y() ); 1063*cdf0e10cSrcweir aUp.Move( aPos.X(), aPos.Y() ); 1064*cdf0e10cSrcweir aUp.Top()++; 1065*cdf0e10cSrcweir aDown.Move( aPos.X(), aPos.Y() ); 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir Color aButtonTextColor; 1068*cdf0e10cSrcweir if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) ) 1069*cdf0e10cSrcweir aButtonTextColor = Color( COL_BLACK ); 1070*cdf0e10cSrcweir else 1071*cdf0e10cSrcweir aButtonTextColor = GetSettings().GetStyleSettings().GetButtonTextColor(); 1072*cdf0e10cSrcweir 1073*cdf0e10cSrcweir if ( GetStyle() & WB_DROPDOWN ) 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir DecorationView aView( pDev ); 1076*cdf0e10cSrcweir sal_uInt16 nStyle = BUTTON_DRAW_NOLIGHTBORDER; 1077*cdf0e10cSrcweir Rectangle aInnerRect = aView.DrawButton( aDD, nStyle ); 1078*cdf0e10cSrcweir SymbolType eSymbol = SYMBOL_SPIN_DOWN; 1079*cdf0e10cSrcweir if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN ) 1080*cdf0e10cSrcweir eSymbol = SYMBOL_SPIN_UPDOWN; 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir nStyle = ( IsEnabled() || ( nFlags & WINDOW_DRAW_NODISABLE ) ) ? 0 : SYMBOL_DRAW_DISABLE; 1083*cdf0e10cSrcweir aView.DrawSymbol( aInnerRect, eSymbol, aButtonTextColor, nStyle ); 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir if ( GetStyle() & WB_SPIN ) 1087*cdf0e10cSrcweir { 1088*cdf0e10cSrcweir ImplDrawSpinButton( pDev, aUp, aDown, sal_False, sal_False, sal_True, sal_True ); 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir pDev->Pop(); 1092*cdf0e10cSrcweir pDev->SetSettings( aOldSettings ); 1093*cdf0e10cSrcweir } 1094*cdf0e10cSrcweir } 1095