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