19f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 59f62ea84SAndrew Rist * distributed with this work for additional information 69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 109f62ea84SAndrew Rist * 119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 129f62ea84SAndrew Rist * 139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 149f62ea84SAndrew Rist * software distributed under the License is distributed on an 159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 179f62ea84SAndrew Rist * specific language governing permissions and limitations 189f62ea84SAndrew Rist * under the License. 199f62ea84SAndrew Rist * 209f62ea84SAndrew Rist *************************************************************/ 219f62ea84SAndrew Rist 229f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "vcl/salnativewidgets.hxx" 25cdf0e10cSrcweir #include "vcl/decoview.hxx" 26cdf0e10cSrcweir #include "vcl/svapp.hxx" 27cdf0e10cSrcweir #include "vcl/timer.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "aqua/salconst.h" 30cdf0e10cSrcweir #include "aqua/salgdi.h" 31cdf0e10cSrcweir #include "aqua/salnativewidgets.h" 32cdf0e10cSrcweir #include "aqua/saldata.hxx" 33cdf0e10cSrcweir #include "aqua/salframe.h" 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include "premac.h" 36cdf0e10cSrcweir #include <Carbon/Carbon.h> 37cdf0e10cSrcweir #include "postmac.h" 38cdf0e10cSrcweir 39cdf0e10cSrcweir class AquaBlinker : public Timer 40cdf0e10cSrcweir { 41cdf0e10cSrcweir AquaSalFrame* mpFrame; 42cdf0e10cSrcweir Rectangle maInvalidateRect; 43cdf0e10cSrcweir 44cdf0e10cSrcweir AquaBlinker( AquaSalFrame* pFrame, const Rectangle& rRect ) 45cdf0e10cSrcweir : mpFrame( pFrame ), maInvalidateRect( rRect ) 46cdf0e10cSrcweir { 47cdf0e10cSrcweir mpFrame->maBlinkers.push_back( this ); 48cdf0e10cSrcweir } 49cdf0e10cSrcweir 50cdf0e10cSrcweir public: 51cdf0e10cSrcweir 52cdf0e10cSrcweir static void Blink( AquaSalFrame*, const Rectangle&, int nTimeout = 80 ); 53cdf0e10cSrcweir 54cdf0e10cSrcweir virtual void Timeout() 55cdf0e10cSrcweir { 56cdf0e10cSrcweir Stop(); 57cdf0e10cSrcweir if( AquaSalFrame::isAlive( mpFrame ) && mpFrame->mbShown ) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir mpFrame->maBlinkers.remove( this ); 60cdf0e10cSrcweir mpFrame->SendPaintEvent( &maInvalidateRect ); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir delete this; 63cdf0e10cSrcweir } 64cdf0e10cSrcweir }; 65cdf0e10cSrcweir 66cdf0e10cSrcweir void AquaBlinker::Blink( AquaSalFrame* pFrame, const Rectangle& rRect, int nTimeout ) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir // prevent repeated paints from triggering themselves all the time 69cdf0e10cSrcweir for( std::list< AquaBlinker* >::const_iterator it = pFrame->maBlinkers.begin(); 70cdf0e10cSrcweir it != pFrame->maBlinkers.end(); ++it ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir if( (*it)->maInvalidateRect == rRect ) 73cdf0e10cSrcweir return; 74cdf0e10cSrcweir } 75cdf0e10cSrcweir AquaBlinker* pNew = new AquaBlinker( pFrame, rRect ); 76cdf0e10cSrcweir pNew->SetTimeout( nTimeout ); 77cdf0e10cSrcweir pNew->Start(); 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir ControlPart ImplgetCounterPart( ControlPart nPart ) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir ControlPart nCounterPart = 0; 83cdf0e10cSrcweir switch (nPart) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir case PART_BUTTON_UP: 86cdf0e10cSrcweir nCounterPart = PART_BUTTON_DOWN; 87cdf0e10cSrcweir break; 88cdf0e10cSrcweir case PART_BUTTON_DOWN: 89cdf0e10cSrcweir nCounterPart = PART_BUTTON_UP; 90cdf0e10cSrcweir break; 91cdf0e10cSrcweir case PART_BUTTON_LEFT: 92cdf0e10cSrcweir nCounterPart = PART_BUTTON_RIGHT; 93cdf0e10cSrcweir break; 94cdf0e10cSrcweir case PART_BUTTON_RIGHT: 95cdf0e10cSrcweir nCounterPart = PART_BUTTON_LEFT; 96cdf0e10cSrcweir break; 97cdf0e10cSrcweir } 98cdf0e10cSrcweir return nCounterPart; 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir 102cdf0e10cSrcweir // Helper returns an HIRect 103cdf0e10cSrcweir 104cdf0e10cSrcweir static HIRect ImplGetHIRectFromRectangle(Rectangle aRect) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir HIRect aHIRect; 107cdf0e10cSrcweir aHIRect.origin.x = static_cast<float>(aRect.Left()); 108cdf0e10cSrcweir aHIRect.origin.y = static_cast<float>(aRect.Top()); 109cdf0e10cSrcweir aHIRect.size.width = static_cast<float>(aRect.GetWidth()); 110cdf0e10cSrcweir aHIRect.size.height = static_cast<float>(aRect.GetHeight()); 111cdf0e10cSrcweir return aHIRect; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir static ThemeButtonValue ImplGetButtonValue( ButtonValue aButtonValue ) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir switch( aButtonValue ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir case BUTTONVALUE_ON: 119cdf0e10cSrcweir return kThemeButtonOn; 120cdf0e10cSrcweir break; 121cdf0e10cSrcweir 122cdf0e10cSrcweir case BUTTONVALUE_OFF: 123cdf0e10cSrcweir return kThemeButtonOff; 124cdf0e10cSrcweir break; 125cdf0e10cSrcweir 126cdf0e10cSrcweir case BUTTONVALUE_MIXED: 127cdf0e10cSrcweir case BUTTONVALUE_DONTKNOW: 128cdf0e10cSrcweir default: 129cdf0e10cSrcweir return kThemeButtonMixed; 130cdf0e10cSrcweir break; 131cdf0e10cSrcweir } 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir static bool AquaGetScrollRect( /* TODO: int nScreen, */ ControlPart nPart, 135cdf0e10cSrcweir const Rectangle& rControlRect, Rectangle& rResultRect ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir bool bRetVal = true; 138cdf0e10cSrcweir rResultRect = rControlRect; 139cdf0e10cSrcweir 140cdf0e10cSrcweir switch( nPart ) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir case PART_BUTTON_UP: 143cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 144cdf0e10cSrcweir rResultRect.Top() = rControlRect.Bottom() - 2*BUTTON_HEIGHT; 145cdf0e10cSrcweir rResultRect.Bottom() = rResultRect.Top() + BUTTON_HEIGHT; 146cdf0e10cSrcweir break; 147cdf0e10cSrcweir 148cdf0e10cSrcweir case PART_BUTTON_DOWN: 149cdf0e10cSrcweir rResultRect.Top() = rControlRect.Bottom() - BUTTON_HEIGHT; 150cdf0e10cSrcweir break; 151cdf0e10cSrcweir 152cdf0e10cSrcweir case PART_BUTTON_LEFT: 153cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 154cdf0e10cSrcweir rResultRect.Left() = rControlRect.Right() - 2*BUTTON_WIDTH; 155cdf0e10cSrcweir rResultRect.Right() = rResultRect.Left() + BUTTON_WIDTH; 156cdf0e10cSrcweir break; 157cdf0e10cSrcweir 158cdf0e10cSrcweir case PART_BUTTON_RIGHT: 159cdf0e10cSrcweir rResultRect.Left() = rControlRect.Right() - BUTTON_WIDTH; 160cdf0e10cSrcweir break; 161cdf0e10cSrcweir 162cdf0e10cSrcweir case PART_TRACK_HORZ_AREA: 163cdf0e10cSrcweir rResultRect.Right() -= BUTTON_WIDTH + 1; 164cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 165cdf0e10cSrcweir rResultRect.Right() -= BUTTON_WIDTH; 166cdf0e10cSrcweir else 167cdf0e10cSrcweir rResultRect.Left() += BUTTON_WIDTH + 1; 168cdf0e10cSrcweir break; 169cdf0e10cSrcweir 170cdf0e10cSrcweir case PART_TRACK_VERT_AREA: 171cdf0e10cSrcweir rResultRect.Bottom() -= BUTTON_HEIGHT + 1; 172cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 173cdf0e10cSrcweir rResultRect.Bottom() -= BUTTON_HEIGHT; 174cdf0e10cSrcweir else 175cdf0e10cSrcweir rResultRect.Top() += BUTTON_HEIGHT + 1; 176cdf0e10cSrcweir break; 177cdf0e10cSrcweir case PART_THUMB_HORZ: 178cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir rResultRect.Left() += 8; 181cdf0e10cSrcweir rResultRect.Right() += 6; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir else 184cdf0e10cSrcweir { 185cdf0e10cSrcweir rResultRect.Left() += 4; 186cdf0e10cSrcweir rResultRect.Right() += 4; 187cdf0e10cSrcweir } 188cdf0e10cSrcweir break; 189cdf0e10cSrcweir case PART_THUMB_VERT: 190cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 191cdf0e10cSrcweir { 192cdf0e10cSrcweir rResultRect.Top() += 8; 193cdf0e10cSrcweir rResultRect.Bottom() += 8; 194cdf0e10cSrcweir } 195cdf0e10cSrcweir else 196cdf0e10cSrcweir { 197cdf0e10cSrcweir rResultRect.Top() += 4; 198cdf0e10cSrcweir rResultRect.Bottom() += 4; 199cdf0e10cSrcweir } 200cdf0e10cSrcweir break; 201cdf0e10cSrcweir case PART_TRACK_HORZ_LEFT: 202cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 203cdf0e10cSrcweir rResultRect.Right() += 8; 204cdf0e10cSrcweir else 205cdf0e10cSrcweir rResultRect.Right() += 4; 206cdf0e10cSrcweir break; 207cdf0e10cSrcweir case PART_TRACK_HORZ_RIGHT: 208cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 209cdf0e10cSrcweir rResultRect.Left() += 6; 210cdf0e10cSrcweir else 211cdf0e10cSrcweir rResultRect.Left() += 4; 212cdf0e10cSrcweir break; 213cdf0e10cSrcweir case PART_TRACK_VERT_UPPER: 214cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 215cdf0e10cSrcweir rResultRect.Bottom() += 8; 216cdf0e10cSrcweir else 217cdf0e10cSrcweir rResultRect.Bottom() += 4; 218cdf0e10cSrcweir break; 219cdf0e10cSrcweir case PART_TRACK_VERT_LOWER: 220cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 221cdf0e10cSrcweir rResultRect.Top() += 8; 222cdf0e10cSrcweir else 223cdf0e10cSrcweir rResultRect.Top() += 4; 224cdf0e10cSrcweir break; 225cdf0e10cSrcweir default: 226cdf0e10cSrcweir bRetVal = false; 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229cdf0e10cSrcweir return bRetVal; 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir /* 233cdf0e10cSrcweir * IsNativeControlSupported() 234cdf0e10cSrcweir * -------------------------- 235cdf0e10cSrcweir * Returns sal_True if the platform supports native 236cdf0e10cSrcweir * drawing of the control defined by nPart. 237cdf0e10cSrcweir * 238cdf0e10cSrcweir */ 239cdf0e10cSrcweir sal_Bool AquaSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir bool bOk = sal_False; 242cdf0e10cSrcweir 243cdf0e10cSrcweir // Native controls are now defaults 244cdf0e10cSrcweir // If you want to disable experimental native controls code, 245cdf0e10cSrcweir // just set the environment variable SAL_NO_NWF to something 246cdf0e10cSrcweir // and vcl controls will be used as default again. 247cdf0e10cSrcweir 248cdf0e10cSrcweir switch( nType ) 249cdf0e10cSrcweir { 250cdf0e10cSrcweir case CTRL_PUSHBUTTON: 251cdf0e10cSrcweir case CTRL_RADIOBUTTON: 252cdf0e10cSrcweir case CTRL_CHECKBOX: 253cdf0e10cSrcweir case CTRL_LISTNODE: 254cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) 255cdf0e10cSrcweir return true; 256cdf0e10cSrcweir break; 257cdf0e10cSrcweir 258cdf0e10cSrcweir case CTRL_SCROLLBAR: 259cdf0e10cSrcweir if( nPart == PART_DRAW_BACKGROUND_HORZ || 260cdf0e10cSrcweir nPart == PART_DRAW_BACKGROUND_VERT || 261cdf0e10cSrcweir nPart == PART_ENTIRE_CONTROL || 262cdf0e10cSrcweir nPart == HAS_THREE_BUTTONS ) 263cdf0e10cSrcweir return true; 264cdf0e10cSrcweir break; 265cdf0e10cSrcweir 266cdf0e10cSrcweir case CTRL_SLIDER: 267cdf0e10cSrcweir if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) 268cdf0e10cSrcweir return true; 269cdf0e10cSrcweir break; 270cdf0e10cSrcweir 271cdf0e10cSrcweir case CTRL_EDITBOX: 272cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 273cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE ) 274cdf0e10cSrcweir return true; 275cdf0e10cSrcweir break; 276cdf0e10cSrcweir 277cdf0e10cSrcweir case CTRL_MULTILINE_EDITBOX: 278cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 279cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE ) 280cdf0e10cSrcweir return true; 281cdf0e10cSrcweir break; 282cdf0e10cSrcweir 283cdf0e10cSrcweir case CTRL_SPINBOX: 284cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 285cdf0e10cSrcweir nPart == PART_ALL_BUTTONS || 286cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE ) 287cdf0e10cSrcweir return true; 288cdf0e10cSrcweir break; 289cdf0e10cSrcweir 290cdf0e10cSrcweir case CTRL_SPINBUTTONS: 291cdf0e10cSrcweir return false; 292cdf0e10cSrcweir break; 293cdf0e10cSrcweir 294cdf0e10cSrcweir case CTRL_COMBOBOX: 295cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 296cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE ) 297cdf0e10cSrcweir return true; 298cdf0e10cSrcweir break; 299cdf0e10cSrcweir 300cdf0e10cSrcweir case CTRL_LISTBOX: 301cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 302cdf0e10cSrcweir nPart == PART_WINDOW || 303cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE || 304cdf0e10cSrcweir nPart == PART_SUB_EDIT 305cdf0e10cSrcweir ) 306cdf0e10cSrcweir return true; 307cdf0e10cSrcweir break; 308cdf0e10cSrcweir 309cdf0e10cSrcweir case CTRL_TAB_ITEM: 310cdf0e10cSrcweir case CTRL_TAB_PANE: 311cdf0e10cSrcweir case CTRL_TAB_BODY: // see vcl/source/window/tabpage.cxx 312cdf0e10cSrcweir case CTRL_FIXEDBORDER: 313cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 314cdf0e10cSrcweir nPart == PART_TABS_DRAW_RTL || 315cdf0e10cSrcweir nPart == HAS_BACKGROUND_TEXTURE ) 316cdf0e10cSrcweir return true; 317cdf0e10cSrcweir break; 318cdf0e10cSrcweir 319cdf0e10cSrcweir // when PART_BUTTON is used, toolbar icons are not highlighted when mouse rolls over. 320cdf0e10cSrcweir // More Aqua compliant 321cdf0e10cSrcweir case CTRL_TOOLBAR: 322cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 323cdf0e10cSrcweir nPart == PART_DRAW_BACKGROUND_HORZ || 324cdf0e10cSrcweir nPart == PART_DRAW_BACKGROUND_VERT) 325cdf0e10cSrcweir return true; 326cdf0e10cSrcweir break; 327cdf0e10cSrcweir 328cdf0e10cSrcweir case CTRL_WINDOW_BACKGROUND: 329cdf0e10cSrcweir if ( nPart == PART_BACKGROUND_WINDOW || 330cdf0e10cSrcweir nPart == PART_BACKGROUND_DIALOG ) 331cdf0e10cSrcweir return true; 332cdf0e10cSrcweir break; 333cdf0e10cSrcweir 334cdf0e10cSrcweir case CTRL_MENUBAR: 335cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) 336cdf0e10cSrcweir return true; 337cdf0e10cSrcweir break; 338cdf0e10cSrcweir 339cdf0e10cSrcweir case CTRL_TOOLTIP: // ** TO DO 340cdf0e10cSrcweir #if 0 341cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) // we don't currently support the tooltip 342cdf0e10cSrcweir return true; 343cdf0e10cSrcweir #endif 344cdf0e10cSrcweir break; 345cdf0e10cSrcweir 346cdf0e10cSrcweir case CTRL_MENU_POPUP: 347cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL || 348cdf0e10cSrcweir nPart == PART_MENU_ITEM || 349cdf0e10cSrcweir nPart == PART_MENU_ITEM_CHECK_MARK || 350cdf0e10cSrcweir nPart == PART_MENU_ITEM_RADIO_MARK) 351cdf0e10cSrcweir return true; 352cdf0e10cSrcweir break; 353cdf0e10cSrcweir case CTRL_PROGRESS: 354cdf0e10cSrcweir case CTRL_INTROPROGRESS: 355cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) 356cdf0e10cSrcweir return true; 357cdf0e10cSrcweir break; 358cdf0e10cSrcweir case CTRL_FRAME: 359cdf0e10cSrcweir if( nPart == PART_BORDER ) 360cdf0e10cSrcweir return true; 361cdf0e10cSrcweir break; 362cdf0e10cSrcweir case CTRL_LISTNET: 363cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) 364cdf0e10cSrcweir return true; 365cdf0e10cSrcweir break; 366cdf0e10cSrcweir } 367cdf0e10cSrcweir 368cdf0e10cSrcweir return bOk; 369cdf0e10cSrcweir } 370cdf0e10cSrcweir 371cdf0e10cSrcweir /* 372cdf0e10cSrcweir * HitTestNativeControl() 373cdf0e10cSrcweir * 374cdf0e10cSrcweir * If the return value is sal_True, bIsInside contains information whether 375cdf0e10cSrcweir * aPos was or was not inside the native widget specified by the 376cdf0e10cSrcweir * nType/nPart combination. 377cdf0e10cSrcweir */ 378cdf0e10cSrcweir sal_Bool AquaSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, 379cdf0e10cSrcweir const Point& rPos, sal_Bool& rIsInside ) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir if ( nType == CTRL_SCROLLBAR ) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir Rectangle aRect; 384cdf0e10cSrcweir bool bValid = AquaGetScrollRect( /* TODO: m_nScreen */ nPart, rControlRegion, aRect ); 385cdf0e10cSrcweir rIsInside = bValid ? aRect.IsInside( rPos ) : sal_False; 386cdf0e10cSrcweir if( GetSalData()->mbIsScrollbarDoubleMax ) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir // in double max mode the actual trough is a little smaller than the track 389cdf0e10cSrcweir // there is some visual filler that is not sensitive 390cdf0e10cSrcweir if( bValid && rIsInside ) 391cdf0e10cSrcweir { 392cdf0e10cSrcweir if( nPart == PART_TRACK_HORZ_AREA ) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir // the left 4 pixels are not hit sensitive 395cdf0e10cSrcweir if( rPos.X() - aRect.Left() < 4 ) 396cdf0e10cSrcweir rIsInside = sal_False; 397cdf0e10cSrcweir } 398cdf0e10cSrcweir else if( nPart == PART_TRACK_VERT_AREA ) 399cdf0e10cSrcweir { 400cdf0e10cSrcweir // the top 4 pixels are not hit sensitive 401cdf0e10cSrcweir if( rPos.Y() - aRect.Top() < 4 ) 402cdf0e10cSrcweir rIsInside = sal_False; 403cdf0e10cSrcweir } 404cdf0e10cSrcweir } 405cdf0e10cSrcweir } 406cdf0e10cSrcweir return bValid; 407cdf0e10cSrcweir } // CTRL_SCROLLBAR 408cdf0e10cSrcweir 409cdf0e10cSrcweir return sal_False; 410cdf0e10cSrcweir } 411cdf0e10cSrcweir 412cdf0e10cSrcweir /* 413cdf0e10cSrcweir kThemeStateInactive = 0, 414cdf0e10cSrcweir kThemeStateActive = 1, 415cdf0e10cSrcweir kThemeStatePressed = 2, 416cdf0e10cSrcweir kThemeStateRollover = 6, 417cdf0e10cSrcweir kThemeStateUnavailable = 7, 418cdf0e10cSrcweir kThemeStateUnavailableInactive = 8 419cdf0e10cSrcweir kThemeStatePressedUp = 2, 420cdf0e10cSrcweir kThemeStatePressedDown = 3 421cdf0e10cSrcweir 422cdf0e10cSrcweir #define CTRL_STATE_ENABLED 0x0001 423cdf0e10cSrcweir #define CTRL_STATE_FOCUSED 0x0002 424cdf0e10cSrcweir #define CTRL_STATE_PRESSED 0x0004 425cdf0e10cSrcweir #define CTRL_STATE_ROLLOVER 0x0008 426cdf0e10cSrcweir #define CTRL_STATE_HIDDEN 0x0010 427cdf0e10cSrcweir #define CTRL_STATE_DEFAULT 0x0020 428cdf0e10cSrcweir #define CTRL_STATE_SELECTED 0x0040 429cdf0e10cSrcweir #define CTRL_CACHING_ALLOWED 0x8000 // set when the control is completely visible (i.e. not clipped) 430cdf0e10cSrcweir */ 431cdf0e10cSrcweir UInt32 AquaSalGraphics::getState( ControlState nState ) 432cdf0e10cSrcweir { 433*bde8a4bdSHerbert Dürr const bool bDrawActive = mpFrame ? ([mpFrame->getNSWindow() isKeyWindow] ? true : false) : true; 434cdf0e10cSrcweir if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive ) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir if( (nState & CTRL_STATE_HIDDEN) == 0 ) 437cdf0e10cSrcweir return kThemeStateInactive; 438cdf0e10cSrcweir else 439cdf0e10cSrcweir return kThemeStateUnavailableInactive; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir 442cdf0e10cSrcweir if( (nState & CTRL_STATE_HIDDEN) != 0 ) 443cdf0e10cSrcweir return kThemeStateUnavailable; 444cdf0e10cSrcweir 445cdf0e10cSrcweir if( (nState & CTRL_STATE_PRESSED) != 0 ) 446cdf0e10cSrcweir return kThemeStatePressed; 447cdf0e10cSrcweir 448cdf0e10cSrcweir return kThemeStateActive; 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir UInt32 AquaSalGraphics::getTrackState( ControlState nState ) 452cdf0e10cSrcweir { 453*bde8a4bdSHerbert Dürr const bool bDrawActive = mpFrame ? ([mpFrame->getNSWindow() isKeyWindow] ? true : false) : true; 454cdf0e10cSrcweir if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive ) 455cdf0e10cSrcweir return kThemeTrackInactive; 456cdf0e10cSrcweir 457cdf0e10cSrcweir return kThemeTrackActive; 458cdf0e10cSrcweir } 459cdf0e10cSrcweir 460cdf0e10cSrcweir /* 461cdf0e10cSrcweir * DrawNativeControl() 462cdf0e10cSrcweir * 463cdf0e10cSrcweir * Draws the requested control described by nPart/nState. 464cdf0e10cSrcweir * 465cdf0e10cSrcweir * rControlRegion: The bounding region of the complete control in VCL frame coordinates. 466cdf0e10cSrcweir * aValue: An optional value (tristate/numerical/string) 467cdf0e10cSrcweir * aCaption: A caption or title string (like button text etc) 468cdf0e10cSrcweir */ 469cdf0e10cSrcweir sal_Bool AquaSalGraphics::drawNativeControl(ControlType nType, 470cdf0e10cSrcweir ControlPart nPart, 471cdf0e10cSrcweir const Rectangle& rControlRegion, 472cdf0e10cSrcweir ControlState nState, 473cdf0e10cSrcweir const ImplControlValue& aValue, 474cdf0e10cSrcweir const rtl::OUString& ) 475cdf0e10cSrcweir { 476cdf0e10cSrcweir sal_Bool bOK = sal_False; 477cdf0e10cSrcweir 478cdf0e10cSrcweir if( ! CheckContext() ) 479cdf0e10cSrcweir return false; 480cdf0e10cSrcweir 481cdf0e10cSrcweir CGContextSaveGState( mrContext ); 482cdf0e10cSrcweir 483cdf0e10cSrcweir Rectangle buttonRect = rControlRegion; 484cdf0e10cSrcweir HIRect rc = ImplGetHIRectFromRectangle(buttonRect); 485cdf0e10cSrcweir 486cdf0e10cSrcweir /** Scrollbar parts code equivalent ** 487cdf0e10cSrcweir PART_BUTTON_UP 101 488cdf0e10cSrcweir PART_BUTTON_DOWN 102 489cdf0e10cSrcweir PART_THUMB_VERT 211 490cdf0e10cSrcweir PART_TRACK_VERT_UPPER 201 491cdf0e10cSrcweir PART_TRACK_VERT_LOWER 203 492cdf0e10cSrcweir 493cdf0e10cSrcweir PART_DRAW_BACKGROUND_HORZ 1000 494cdf0e10cSrcweir PART_DRAW_BACKGROUND_VERT 1001 495cdf0e10cSrcweir **/ 496cdf0e10cSrcweir 497cdf0e10cSrcweir switch( nType ) 498cdf0e10cSrcweir { 499cdf0e10cSrcweir 500cdf0e10cSrcweir case CTRL_COMBOBOX: 501cdf0e10cSrcweir if ( nPart == HAS_BACKGROUND_TEXTURE || 502cdf0e10cSrcweir nPart == PART_ENTIRE_CONTROL ) 503cdf0e10cSrcweir { 504cdf0e10cSrcweir HIThemeButtonDrawInfo aComboInfo; 505cdf0e10cSrcweir aComboInfo.version = 0; 506cdf0e10cSrcweir aComboInfo.kind = kThemeComboBox; 507cdf0e10cSrcweir aComboInfo.state = getState( nState ); 508cdf0e10cSrcweir aComboInfo.value = kThemeButtonOn; 509cdf0e10cSrcweir aComboInfo.adornment = kThemeAdornmentNone; 510cdf0e10cSrcweir 511cdf0e10cSrcweir if( (nState & CTRL_STATE_FOCUSED) != 0 ) 512cdf0e10cSrcweir aComboInfo.adornment |= kThemeAdornmentFocus; 513cdf0e10cSrcweir 514cdf0e10cSrcweir HIThemeDrawButton(&rc, &aComboInfo, mrContext, kHIThemeOrientationNormal,&rc); 515cdf0e10cSrcweir bOK = true; 516cdf0e10cSrcweir } 517cdf0e10cSrcweir break; 518cdf0e10cSrcweir 519cdf0e10cSrcweir case CTRL_FIXEDBORDER: 520cdf0e10cSrcweir case CTRL_TOOLBAR: 521cdf0e10cSrcweir { 522cdf0e10cSrcweir HIThemeMenuItemDrawInfo aMenuItemDrawInfo; 523cdf0e10cSrcweir aMenuItemDrawInfo.version = 0; 524cdf0e10cSrcweir aMenuItemDrawInfo.state = kThemeMenuActive; 525cdf0e10cSrcweir aMenuItemDrawInfo.itemType = kThemeMenuItemHierBackground; 526cdf0e10cSrcweir HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,NULL); 527cdf0e10cSrcweir bOK = true; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir break; 530cdf0e10cSrcweir 531cdf0e10cSrcweir case CTRL_WINDOW_BACKGROUND: 532cdf0e10cSrcweir { 533cdf0e10cSrcweir HIThemeBackgroundDrawInfo aThemeBackgroundInfo; 534cdf0e10cSrcweir aThemeBackgroundInfo.version = 0; 535cdf0e10cSrcweir aThemeBackgroundInfo.state = getState( nState ); 536cdf0e10cSrcweir aThemeBackgroundInfo.kind = kThemeBrushDialogBackgroundInactive; 537cdf0e10cSrcweir // FIXME: without this magical offset there is a 2 pixel black border on the right and bottom 538cdf0e10cSrcweir rc.size.width += 2; 539cdf0e10cSrcweir rc.size.height += 2; 540cdf0e10cSrcweir 541cdf0e10cSrcweir HIThemeApplyBackground( &rc, &aThemeBackgroundInfo, mrContext, kHIThemeOrientationNormal); 542cdf0e10cSrcweir CGContextFillRect( mrContext, rc ); 543cdf0e10cSrcweir bOK = true; 544cdf0e10cSrcweir } 545cdf0e10cSrcweir break; 546cdf0e10cSrcweir 547cdf0e10cSrcweir case CTRL_MENUBAR: 548cdf0e10cSrcweir case CTRL_MENU_POPUP: 549cdf0e10cSrcweir { 550cdf0e10cSrcweir if ((nPart == PART_ENTIRE_CONTROL) || (nPart == PART_MENU_ITEM )|| (nPart == HAS_BACKGROUND_TEXTURE )) 551cdf0e10cSrcweir { 552cdf0e10cSrcweir // FIXME: without this magical offset there is a 2 pixel black border on the right 553cdf0e10cSrcweir rc.size.width += 2; 554cdf0e10cSrcweir 555cdf0e10cSrcweir HIThemeMenuDrawInfo aMenuInfo; 556cdf0e10cSrcweir aMenuInfo.version = 0; 557cdf0e10cSrcweir aMenuInfo.menuType = kThemeMenuTypePullDown; 558cdf0e10cSrcweir 559cdf0e10cSrcweir HIThemeMenuItemDrawInfo aMenuItemDrawInfo; 560cdf0e10cSrcweir // the Aqua grey theme when the item is selected is drawn here. 561cdf0e10cSrcweir aMenuItemDrawInfo.itemType = kThemeMenuItemPlain; 562cdf0e10cSrcweir 563cdf0e10cSrcweir if ((nPart == PART_MENU_ITEM ) && (nState & CTRL_STATE_SELECTED)) 564cdf0e10cSrcweir { 565cdf0e10cSrcweir // the blue theme when the item is selected is drawn here. 566cdf0e10cSrcweir aMenuItemDrawInfo.state = kThemeMenuSelected; 567cdf0e10cSrcweir } 568cdf0e10cSrcweir else 569cdf0e10cSrcweir { 570cdf0e10cSrcweir // normal color for non selected item 571cdf0e10cSrcweir aMenuItemDrawInfo.state = kThemeMenuActive; 572cdf0e10cSrcweir } 573cdf0e10cSrcweir 574cdf0e10cSrcweir // repaints the background of the pull down menu 575cdf0e10cSrcweir HIThemeDrawMenuBackground(&rc,&aMenuInfo,mrContext,kHIThemeOrientationNormal); 576cdf0e10cSrcweir 577cdf0e10cSrcweir // repaints the item either blue (selected) and/or Aqua grey (active only) 578cdf0e10cSrcweir HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,&rc); 579cdf0e10cSrcweir 580cdf0e10cSrcweir bOK = true; 581cdf0e10cSrcweir } 582cdf0e10cSrcweir else if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) { 583cdf0e10cSrcweir if( nState & CTRL_STATE_PRESSED ) {//checked, else it is not displayed (see vcl/source/window/menu.cxx) 584cdf0e10cSrcweir HIThemeTextInfo aTextInfo; 585cdf0e10cSrcweir aTextInfo.version = 0; 586cdf0e10cSrcweir aTextInfo.state = ((nState & CTRL_STATE_ENABLED)==0) ? kThemeStateInactive: kThemeStateActive; 587cdf0e10cSrcweir aTextInfo.fontID = kThemeMenuItemMarkFont; 588cdf0e10cSrcweir aTextInfo.horizontalFlushness=kHIThemeTextHorizontalFlushCenter; 589cdf0e10cSrcweir aTextInfo.verticalFlushness=kHIThemeTextVerticalFlushTop; 590cdf0e10cSrcweir aTextInfo.options=kHIThemeTextBoxOptionNone; 591cdf0e10cSrcweir aTextInfo.truncationPosition=kHIThemeTextTruncationNone; 592cdf0e10cSrcweir //aTextInfo.truncationMaxLines unused because of kHIThemeTextTruncationNone 593cdf0e10cSrcweir 594cdf0e10cSrcweir if( nState & CTRL_STATE_SELECTED) aTextInfo.state = kThemeStatePressed; //item highlighted 595cdf0e10cSrcweir 596cdf0e10cSrcweir UniChar mark=( nPart == PART_MENU_ITEM_CHECK_MARK ) ? kCheckUnicode: kBulletUnicode;//0x2713; 597cdf0e10cSrcweir CFStringRef cfString = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &mark, 1, kCFAllocatorNull); 598cdf0e10cSrcweir HIThemeDrawTextBox(cfString, &rc, &aTextInfo, mrContext, kHIThemeOrientationNormal); 599cdf0e10cSrcweir if (cfString) 600cdf0e10cSrcweir CFRelease(cfString); 601cdf0e10cSrcweir 602cdf0e10cSrcweir bOK = true; 603cdf0e10cSrcweir } 604cdf0e10cSrcweir } 605cdf0e10cSrcweir } 606cdf0e10cSrcweir break; 607cdf0e10cSrcweir 608cdf0e10cSrcweir case CTRL_PUSHBUTTON: 609cdf0e10cSrcweir { 610cdf0e10cSrcweir // [ FIXME] : instead of use a value, vcl can retrieve corect values on the fly (to be implemented) 611cdf0e10cSrcweir const int PB_Mini_Height = 15; 612cdf0e10cSrcweir const int PB_Norm_Height = 21; 613cdf0e10cSrcweir 614cdf0e10cSrcweir HIThemeButtonDrawInfo aPushInfo; 615cdf0e10cSrcweir aPushInfo.version = 0; 616cdf0e10cSrcweir 617cdf0e10cSrcweir // no animation 618cdf0e10cSrcweir aPushInfo.animation.time.start = 0; 619cdf0e10cSrcweir aPushInfo.animation.time.current = 0; 620cdf0e10cSrcweir PushButtonValue* pPBVal = aValue.getType() == CTRL_PUSHBUTTON ? (PushButtonValue*)&aValue : NULL; 621cdf0e10cSrcweir int nPaintHeight = static_cast<int>(rc.size.height); 622cdf0e10cSrcweir 623cdf0e10cSrcweir if( pPBVal && pPBVal->mbBevelButton ) 624cdf0e10cSrcweir { 625cdf0e10cSrcweir aPushInfo.kind = kThemeRoundedBevelButton; 626cdf0e10cSrcweir } 627cdf0e10cSrcweir else if( rc.size.height <= PB_Norm_Height ) 628cdf0e10cSrcweir { 629cdf0e10cSrcweir aPushInfo.kind = kThemePushButtonMini; 630cdf0e10cSrcweir nPaintHeight = PB_Mini_Height; 631cdf0e10cSrcweir } 632cdf0e10cSrcweir else if( pPBVal->mbSingleLine || rc.size.height < (PB_Norm_Height + PB_Norm_Height/2) ) 633cdf0e10cSrcweir { 634cdf0e10cSrcweir aPushInfo.kind = kThemePushButtonNormal; 635cdf0e10cSrcweir nPaintHeight = PB_Norm_Height; 636cdf0e10cSrcweir 637cdf0e10cSrcweir // avoid clipping when focused 638cdf0e10cSrcweir rc.origin.x += FOCUS_RING_WIDTH/2; 639cdf0e10cSrcweir rc.size.width -= FOCUS_RING_WIDTH; 640cdf0e10cSrcweir 641cdf0e10cSrcweir if( (nState & CTRL_STATE_DEFAULT) != 0 ) 642cdf0e10cSrcweir { 643cdf0e10cSrcweir AquaBlinker::Blink( mpFrame, buttonRect ); 644cdf0e10cSrcweir // show correct animation phase 645cdf0e10cSrcweir aPushInfo.animation.time.current = CFAbsoluteTimeGetCurrent(); 646cdf0e10cSrcweir } 647cdf0e10cSrcweir } 648cdf0e10cSrcweir else 649cdf0e10cSrcweir aPushInfo.kind = kThemeBevelButton; 650cdf0e10cSrcweir 651cdf0e10cSrcweir // translate the origin for controls with fixed paint height 652cdf0e10cSrcweir // so content ends up somewhere sensible 653cdf0e10cSrcweir int delta_y = static_cast<int>(rc.size.height) - nPaintHeight; 654cdf0e10cSrcweir rc.origin.y += delta_y/2; 655cdf0e10cSrcweir 656cdf0e10cSrcweir aPushInfo.state = getState( nState ); 657cdf0e10cSrcweir aPushInfo.value = ImplGetButtonValue( aValue.getTristateVal() ); 658cdf0e10cSrcweir 659cdf0e10cSrcweir aPushInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ? 660cdf0e10cSrcweir kThemeAdornmentDefault : 661cdf0e10cSrcweir kThemeAdornmentNone; 662cdf0e10cSrcweir if( (nState & CTRL_STATE_FOCUSED) != 0 ) 663cdf0e10cSrcweir aPushInfo.adornment |= kThemeAdornmentFocus; 664cdf0e10cSrcweir 665cdf0e10cSrcweir HIThemeDrawButton( &rc, &aPushInfo, mrContext, kHIThemeOrientationNormal, NULL ); 666cdf0e10cSrcweir bOK = true; 667cdf0e10cSrcweir } 668cdf0e10cSrcweir break; 669cdf0e10cSrcweir 670cdf0e10cSrcweir case CTRL_RADIOBUTTON: 671cdf0e10cSrcweir case CTRL_CHECKBOX: 672cdf0e10cSrcweir { 673cdf0e10cSrcweir HIThemeButtonDrawInfo aInfo; 674cdf0e10cSrcweir aInfo.version = 0; 675cdf0e10cSrcweir switch( nType ) 676cdf0e10cSrcweir { 677cdf0e10cSrcweir case CTRL_RADIOBUTTON: if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeRadioButton; 678cdf0e10cSrcweir else aInfo.kind = kThemeSmallRadioButton; 679cdf0e10cSrcweir break; 680cdf0e10cSrcweir case CTRL_CHECKBOX: if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeCheckBox; 681cdf0e10cSrcweir else aInfo.kind = kThemeSmallCheckBox; 682cdf0e10cSrcweir break; 683cdf0e10cSrcweir } 684cdf0e10cSrcweir 685cdf0e10cSrcweir aInfo.state = getState( nState ); 686cdf0e10cSrcweir 687cdf0e10cSrcweir ButtonValue aButtonValue = aValue.getTristateVal(); 688cdf0e10cSrcweir aInfo.value = ImplGetButtonValue( aButtonValue ); 689cdf0e10cSrcweir 690cdf0e10cSrcweir aInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ? 691cdf0e10cSrcweir kThemeAdornmentDefault : 692cdf0e10cSrcweir kThemeAdornmentNone; 693cdf0e10cSrcweir if( (nState & CTRL_STATE_FOCUSED) != 0 ) 694cdf0e10cSrcweir aInfo.adornment |= kThemeAdornmentFocus; 695cdf0e10cSrcweir HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL ); 696cdf0e10cSrcweir bOK = true; 697cdf0e10cSrcweir } 698cdf0e10cSrcweir break; 699cdf0e10cSrcweir 700cdf0e10cSrcweir case CTRL_LISTNODE: 701cdf0e10cSrcweir { 702cdf0e10cSrcweir ButtonValue aButtonValue = aValue.getTristateVal(); 703cdf0e10cSrcweir 704cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() && aButtonValue == BUTTONVALUE_OFF ) 705cdf0e10cSrcweir { 706cdf0e10cSrcweir // FIXME: a value of kThemeDisclosureLeft 707cdf0e10cSrcweir // should draw a theme compliant left disclosure triangle 708cdf0e10cSrcweir // sadly this does not seem to work, so we'll draw a left 709cdf0e10cSrcweir // grey equilateral triangle here ourselves. 710cdf0e10cSrcweir // Perhaps some other HIThemeButtonDrawInfo setting would do the trick ? 711cdf0e10cSrcweir 712cdf0e10cSrcweir CGContextSetShouldAntialias( mrContext, true ); 713cdf0e10cSrcweir float aGrey[] = { 0.45, 0.45, 0.45, 1.0 }; 714cdf0e10cSrcweir CGContextSetFillColor( mrContext, aGrey ); 715cdf0e10cSrcweir CGContextBeginPath( mrContext ); 716cdf0e10cSrcweir float x = rc.origin.x + rc.size.width; 717cdf0e10cSrcweir float y = rc.origin.y; 718cdf0e10cSrcweir CGContextMoveToPoint( mrContext, x, y ); 719cdf0e10cSrcweir y += rc.size.height; 720cdf0e10cSrcweir CGContextAddLineToPoint( mrContext, x, y ); 721cdf0e10cSrcweir x -= rc.size.height * 0.866; // cos( 30 degree ) is approx. 0.866 722cdf0e10cSrcweir y -= rc.size.height/2; 723cdf0e10cSrcweir CGContextAddLineToPoint( mrContext, x, y ); 724cdf0e10cSrcweir CGContextDrawPath( mrContext, kCGPathEOFill ); 725cdf0e10cSrcweir } 726cdf0e10cSrcweir else 727cdf0e10cSrcweir { 728cdf0e10cSrcweir HIThemeButtonDrawInfo aInfo; 729cdf0e10cSrcweir aInfo.version = 0; 730cdf0e10cSrcweir aInfo.kind = kThemeDisclosureTriangle; 731cdf0e10cSrcweir aInfo.value = kThemeDisclosureRight; 732cdf0e10cSrcweir aInfo.state = getState( nState ); 733cdf0e10cSrcweir 734cdf0e10cSrcweir aInfo.adornment = kThemeAdornmentNone; 735cdf0e10cSrcweir 736cdf0e10cSrcweir switch( aButtonValue ) { 737cdf0e10cSrcweir case BUTTONVALUE_ON: aInfo.value = kThemeDisclosureDown;//expanded 738cdf0e10cSrcweir break; 739cdf0e10cSrcweir case BUTTONVALUE_OFF: 740cdf0e10cSrcweir // FIXME: this should have drawn a theme compliant disclosure triangle 741cdf0e10cSrcweir // (see above) 742cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir aInfo.value = kThemeDisclosureLeft;//collapsed, RTL 745cdf0e10cSrcweir } 746cdf0e10cSrcweir break; 747cdf0e10cSrcweir case BUTTONVALUE_DONTKNOW: //what to do? 748cdf0e10cSrcweir default: 749cdf0e10cSrcweir break; 750cdf0e10cSrcweir } 751cdf0e10cSrcweir 752cdf0e10cSrcweir HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL ); 753cdf0e10cSrcweir } 754cdf0e10cSrcweir bOK = true; 755cdf0e10cSrcweir } 756cdf0e10cSrcweir break; 757cdf0e10cSrcweir 758cdf0e10cSrcweir case CTRL_PROGRESS: 759cdf0e10cSrcweir case CTRL_INTROPROGRESS: 760cdf0e10cSrcweir { 761cdf0e10cSrcweir long nProgressWidth = aValue.getNumericVal(); 762cdf0e10cSrcweir HIThemeTrackDrawInfo aTrackInfo; 763cdf0e10cSrcweir aTrackInfo.version = 0; 764cdf0e10cSrcweir aTrackInfo.kind = (rc.size.height > 10) ? kThemeProgressBarLarge : kThemeProgressBarMedium; 765cdf0e10cSrcweir aTrackInfo.bounds = rc; 766cdf0e10cSrcweir aTrackInfo.min = 0; 767cdf0e10cSrcweir aTrackInfo.max = static_cast<SInt32>(rc.size.width); 768cdf0e10cSrcweir aTrackInfo.value = nProgressWidth; 769cdf0e10cSrcweir aTrackInfo.reserved = 0; 770cdf0e10cSrcweir aTrackInfo.bounds.origin.y -= 2; // FIXME: magic for shadow 771cdf0e10cSrcweir aTrackInfo.bounds.size.width -= 2; // FIXME: magic for shadow 772cdf0e10cSrcweir aTrackInfo.attributes = kThemeTrackHorizontal; 773cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 774cdf0e10cSrcweir aTrackInfo.attributes |= kThemeTrackRightToLeft; 775cdf0e10cSrcweir aTrackInfo.enableState = getTrackState( nState ); 776cdf0e10cSrcweir // the intro bitmap never gets key anyway; we want to draw that enabled 777cdf0e10cSrcweir if( nType == CTRL_INTROPROGRESS ) 778cdf0e10cSrcweir aTrackInfo.enableState = kThemeTrackActive; 779cdf0e10cSrcweir aTrackInfo.filler1 = 0; 780cdf0e10cSrcweir aTrackInfo.trackInfo.progress.phase = static_cast<UInt8>(CFAbsoluteTimeGetCurrent()*10.0); 781cdf0e10cSrcweir 782cdf0e10cSrcweir HIThemeDrawTrack( &aTrackInfo, NULL, mrContext, kHIThemeOrientationNormal ); 783cdf0e10cSrcweir bOK = true; 784cdf0e10cSrcweir } 785cdf0e10cSrcweir break; 786cdf0e10cSrcweir 787cdf0e10cSrcweir case CTRL_SLIDER: 788cdf0e10cSrcweir { 789cdf0e10cSrcweir SliderValue* pSLVal = (SliderValue*)&aValue; 790cdf0e10cSrcweir 791cdf0e10cSrcweir HIThemeTrackDrawInfo aTrackDraw; 792cdf0e10cSrcweir aTrackDraw.kind = kThemeSliderMedium; 793cdf0e10cSrcweir if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) 794cdf0e10cSrcweir { 795cdf0e10cSrcweir aTrackDraw.bounds = rc; 796cdf0e10cSrcweir aTrackDraw.min = pSLVal->mnMin; 797cdf0e10cSrcweir aTrackDraw.max = pSLVal->mnMax;; 798cdf0e10cSrcweir aTrackDraw.value = pSLVal->mnCur; 799cdf0e10cSrcweir aTrackDraw.reserved = 0; 800cdf0e10cSrcweir aTrackDraw.attributes = kThemeTrackShowThumb; 801cdf0e10cSrcweir if( nPart == PART_TRACK_HORZ_AREA ) 802cdf0e10cSrcweir aTrackDraw.attributes |= kThemeTrackHorizontal; 803cdf0e10cSrcweir aTrackDraw.enableState = (nState & CTRL_STATE_ENABLED) 804cdf0e10cSrcweir ? kThemeTrackActive : kThemeTrackInactive; 805cdf0e10cSrcweir 806cdf0e10cSrcweir SliderTrackInfo aSlideInfo; 807cdf0e10cSrcweir aSlideInfo.thumbDir = kThemeThumbUpward; 808cdf0e10cSrcweir aSlideInfo.pressState = 0; 809cdf0e10cSrcweir aTrackDraw.trackInfo.slider = aSlideInfo; 810cdf0e10cSrcweir 811cdf0e10cSrcweir HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal ); 812cdf0e10cSrcweir bOK = true; 813cdf0e10cSrcweir } 814cdf0e10cSrcweir } 815cdf0e10cSrcweir break; 816cdf0e10cSrcweir 817cdf0e10cSrcweir case CTRL_SCROLLBAR: 818cdf0e10cSrcweir { 8193460f9c8SHerbert Dürr const ScrollbarValue* pScrollbarVal = (aValue.getType() == CTRL_SCROLLBAR) ? static_cast<const ScrollbarValue*>(&aValue) : NULL; 820cdf0e10cSrcweir 821cdf0e10cSrcweir if( nPart == PART_DRAW_BACKGROUND_VERT || 822cdf0e10cSrcweir nPart == PART_DRAW_BACKGROUND_HORZ ) 823cdf0e10cSrcweir { 824cdf0e10cSrcweir HIThemeTrackDrawInfo aTrackDraw; 825cdf0e10cSrcweir aTrackDraw.kind = kThemeMediumScrollBar; 826cdf0e10cSrcweir // FIXME: the scrollbar length must be adjusted 827cdf0e10cSrcweir if (nPart == PART_DRAW_BACKGROUND_VERT) 828cdf0e10cSrcweir rc.size.height += 2; 829cdf0e10cSrcweir else 830cdf0e10cSrcweir rc.size.width += 2; 831cdf0e10cSrcweir 832cdf0e10cSrcweir aTrackDraw.bounds = rc; 833cdf0e10cSrcweir aTrackDraw.min = pScrollbarVal->mnMin; 834cdf0e10cSrcweir aTrackDraw.max = pScrollbarVal->mnMax - pScrollbarVal->mnVisibleSize; 835cdf0e10cSrcweir aTrackDraw.value = pScrollbarVal->mnCur; 836cdf0e10cSrcweir aTrackDraw.reserved = 0; 837cdf0e10cSrcweir aTrackDraw.attributes = kThemeTrackShowThumb; 838cdf0e10cSrcweir if( nPart == PART_DRAW_BACKGROUND_HORZ ) 839cdf0e10cSrcweir aTrackDraw.attributes |= kThemeTrackHorizontal; 840cdf0e10cSrcweir aTrackDraw.enableState = getTrackState( nState ); 841cdf0e10cSrcweir 842cdf0e10cSrcweir ScrollBarTrackInfo aScrollInfo; 843cdf0e10cSrcweir aScrollInfo.viewsize = pScrollbarVal->mnVisibleSize; 844cdf0e10cSrcweir aScrollInfo.pressState = 0; 845cdf0e10cSrcweir 846cdf0e10cSrcweir if ( pScrollbarVal->mnButton1State & CTRL_STATE_ENABLED ) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir if ( pScrollbarVal->mnButton1State & CTRL_STATE_PRESSED ) 849cdf0e10cSrcweir aScrollInfo.pressState = kThemeTopOutsideArrowPressed; 850cdf0e10cSrcweir } 851cdf0e10cSrcweir 852cdf0e10cSrcweir if ( pScrollbarVal->mnButton2State & CTRL_STATE_ENABLED ) 853cdf0e10cSrcweir { 854cdf0e10cSrcweir if ( pScrollbarVal->mnButton2State & CTRL_STATE_PRESSED ) 855cdf0e10cSrcweir aScrollInfo.pressState = kThemeBottomOutsideArrowPressed; 856cdf0e10cSrcweir } 857cdf0e10cSrcweir 858cdf0e10cSrcweir if ( pScrollbarVal->mnThumbState & CTRL_STATE_ENABLED ) 859cdf0e10cSrcweir { 860cdf0e10cSrcweir if ( pScrollbarVal->mnThumbState & CTRL_STATE_PRESSED ) 861cdf0e10cSrcweir aScrollInfo.pressState = kThemeThumbPressed; 862cdf0e10cSrcweir } 863cdf0e10cSrcweir 864cdf0e10cSrcweir aTrackDraw.trackInfo.scrollbar = aScrollInfo; 865cdf0e10cSrcweir 866cdf0e10cSrcweir HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal ); 867cdf0e10cSrcweir bOK = true; 868cdf0e10cSrcweir } 869cdf0e10cSrcweir } 870cdf0e10cSrcweir break; 871cdf0e10cSrcweir 872cdf0e10cSrcweir //#define OLD_TAB_STYLE 873cdf0e10cSrcweir #ifdef OLD_TAB_STYLE 874cdf0e10cSrcweir case CTRL_TAB_PANE: 875cdf0e10cSrcweir { 876cdf0e10cSrcweir HIThemeTabPaneDrawInfo aTabPaneDrawInfo; 877cdf0e10cSrcweir aTabPaneDrawInfo.version = 0; 878cdf0e10cSrcweir aTabPaneDrawInfo.state = kThemeStateActive; 879cdf0e10cSrcweir aTabPaneDrawInfo.direction=kThemeTabNorth; 880cdf0e10cSrcweir aTabPaneDrawInfo.size=kHIThemeTabSizeNormal; 881cdf0e10cSrcweir 882cdf0e10cSrcweir //the border is outside the rect rc for Carbon 883cdf0e10cSrcweir //but for VCL it should be inside 884cdf0e10cSrcweir rc.origin.x+=1; 885cdf0e10cSrcweir rc.size.width-=2; 886cdf0e10cSrcweir 887cdf0e10cSrcweir HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal); 888cdf0e10cSrcweir bOK = true; 889cdf0e10cSrcweir } 890cdf0e10cSrcweir break; 891cdf0e10cSrcweir 892cdf0e10cSrcweir case CTRL_TAB_ITEM: 893cdf0e10cSrcweir { 894cdf0e10cSrcweir HIThemeTabDrawInfo aTabItemDrawInfo; 895cdf0e10cSrcweir aTabItemDrawInfo.version=0; 896cdf0e10cSrcweir aTabItemDrawInfo.style=kThemeTabNonFront; 897cdf0e10cSrcweir aTabItemDrawInfo.direction=kThemeTabNorth; 898cdf0e10cSrcweir aTabItemDrawInfo.size=kHIThemeTabSizeNormal; 899cdf0e10cSrcweir aTabItemDrawInfo.adornment=kHIThemeTabAdornmentNone; 900cdf0e10cSrcweir 901cdf0e10cSrcweir if(nState & CTRL_STATE_SELECTED) { 902cdf0e10cSrcweir aTabItemDrawInfo.style=kThemeTabFront; 903cdf0e10cSrcweir } 904cdf0e10cSrcweir if(nState & CTRL_STATE_FOCUSED) { 905cdf0e10cSrcweir aTabItemDrawInfo.adornment=kHIThemeTabAdornmentFocus; 906cdf0e10cSrcweir } 907cdf0e10cSrcweir 908cdf0e10cSrcweir /*if(rc.size.height>=TAB_HEIGHT_NORMAL) rc.size.height=TAB_HEIGHT_NORMAL; 909cdf0e10cSrcweir else if(rc.size.height>=TAB_HEIGHT_SMALL) rc.size.height=TAB_HEIGHT_SMALL; 910cdf0e10cSrcweir else rc.size.height=TAB_HEIGHT_MINI;*/ 911cdf0e10cSrcweir //now we only use the default size 912cdf0e10cSrcweir rc.size.height=TAB_HEIGHT_NORMAL; 913cdf0e10cSrcweir 914cdf0e10cSrcweir HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc ); 915cdf0e10cSrcweir 916cdf0e10cSrcweir bOK=true; 917cdf0e10cSrcweir } 918cdf0e10cSrcweir break; 919cdf0e10cSrcweir #else 920cdf0e10cSrcweir case CTRL_TAB_PANE: 921cdf0e10cSrcweir { 922cdf0e10cSrcweir HIThemeTabPaneDrawInfo aTabPaneDrawInfo; 923cdf0e10cSrcweir aTabPaneDrawInfo.version = 1; 924cdf0e10cSrcweir aTabPaneDrawInfo.state = kThemeStateActive; 925cdf0e10cSrcweir aTabPaneDrawInfo.direction=kThemeTabNorth; 926cdf0e10cSrcweir aTabPaneDrawInfo.size=kHIThemeTabSizeNormal; 927cdf0e10cSrcweir aTabPaneDrawInfo.kind=kHIThemeTabKindNormal; 928cdf0e10cSrcweir 929cdf0e10cSrcweir //the border is outside the rect rc for Carbon 930cdf0e10cSrcweir //but for VCL it should be inside 931cdf0e10cSrcweir rc.origin.x+=1; 932cdf0e10cSrcweir rc.origin.y-=TAB_HEIGHT_NORMAL/2; 933cdf0e10cSrcweir rc.size.height+=TAB_HEIGHT_NORMAL/2; 934cdf0e10cSrcweir rc.size.width-=2; 935cdf0e10cSrcweir 936cdf0e10cSrcweir HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal); 937cdf0e10cSrcweir 938cdf0e10cSrcweir bOK = true; 939cdf0e10cSrcweir } 940cdf0e10cSrcweir break; 941cdf0e10cSrcweir 942cdf0e10cSrcweir case CTRL_TAB_ITEM: 943cdf0e10cSrcweir { 944cdf0e10cSrcweir HIThemeTabDrawInfo aTabItemDrawInfo; 945cdf0e10cSrcweir aTabItemDrawInfo.version=1; 946cdf0e10cSrcweir aTabItemDrawInfo.style=kThemeTabNonFront; 947cdf0e10cSrcweir aTabItemDrawInfo.direction=kThemeTabNorth; 948cdf0e10cSrcweir aTabItemDrawInfo.size=kHIThemeTabSizeNormal; 949cdf0e10cSrcweir aTabItemDrawInfo.adornment=kHIThemeTabAdornmentTrailingSeparator; 950cdf0e10cSrcweir //State 951cdf0e10cSrcweir if(nState & CTRL_STATE_SELECTED) { 952cdf0e10cSrcweir aTabItemDrawInfo.style=kThemeTabFront; 953cdf0e10cSrcweir } 954cdf0e10cSrcweir if(nState & CTRL_STATE_FOCUSED) { 955cdf0e10cSrcweir aTabItemDrawInfo.adornment|=kHIThemeTabAdornmentFocus; 956cdf0e10cSrcweir } 957cdf0e10cSrcweir 958cdf0e10cSrcweir //first, last or middle tab 959cdf0e10cSrcweir aTabItemDrawInfo.position=kHIThemeTabPositionMiddle; 960cdf0e10cSrcweir 961cdf0e10cSrcweir TabitemValue* pTabValue = (TabitemValue *) &aValue; 962cdf0e10cSrcweir unsigned int nAlignment = pTabValue->mnAlignment; 963cdf0e10cSrcweir //TABITEM_LEFTALIGNED (and TABITEM_RIGHTALIGNED) for the leftmost (or rightmost) tab 964cdf0e10cSrcweir //when there are several lines of tabs because there is only one first tab and one 965cdf0e10cSrcweir //last tab and TABITEM_FIRST_IN_GROUP (and TABITEM_LAST_IN_GROUP) because when the 966cdf0e10cSrcweir //line width is different from window width, there may not be TABITEM_RIGHTALIGNED 967cdf0e10cSrcweir if( ( (nAlignment & TABITEM_LEFTALIGNED)&&(nAlignment & TABITEM_RIGHTALIGNED) ) || 968cdf0e10cSrcweir ( (nAlignment & TABITEM_FIRST_IN_GROUP)&&(nAlignment & TABITEM_LAST_IN_GROUP) ) 969cdf0e10cSrcweir ) //tab alone 970cdf0e10cSrcweir aTabItemDrawInfo.position=kHIThemeTabPositionOnly; 971cdf0e10cSrcweir else if((nAlignment & TABITEM_LEFTALIGNED)||(nAlignment & TABITEM_FIRST_IN_GROUP)) 972cdf0e10cSrcweir aTabItemDrawInfo.position=kHIThemeTabPositionFirst; 973cdf0e10cSrcweir else if((nAlignment & TABITEM_RIGHTALIGNED)||(nAlignment & TABITEM_LAST_IN_GROUP)) 974cdf0e10cSrcweir aTabItemDrawInfo.position=kHIThemeTabPositionLast; 975cdf0e10cSrcweir 976cdf0e10cSrcweir //support for RTL 977cdf0e10cSrcweir //see issue 79748 978cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) { 979cdf0e10cSrcweir if( aTabItemDrawInfo.position == kHIThemeTabPositionFirst ) 980cdf0e10cSrcweir aTabItemDrawInfo.position = kHIThemeTabPositionLast; 981cdf0e10cSrcweir else if( aTabItemDrawInfo.position == kHIThemeTabPositionLast ) 982cdf0e10cSrcweir aTabItemDrawInfo.position = kHIThemeTabPositionFirst; 983cdf0e10cSrcweir } 984cdf0e10cSrcweir 985cdf0e10cSrcweir rc.size.width+=2;//because VCL has 2 empty pixels between 2 tabs 986cdf0e10cSrcweir rc.origin.x-=1; 987cdf0e10cSrcweir 988cdf0e10cSrcweir HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc ); 989cdf0e10cSrcweir 990cdf0e10cSrcweir bOK=true; 991cdf0e10cSrcweir } 992cdf0e10cSrcweir break; 993cdf0e10cSrcweir #endif 994cdf0e10cSrcweir 995cdf0e10cSrcweir case CTRL_LISTBOX: 996cdf0e10cSrcweir switch( nPart) 997cdf0e10cSrcweir { 998cdf0e10cSrcweir case PART_ENTIRE_CONTROL: 999cdf0e10cSrcweir case PART_BUTTON_DOWN: 1000cdf0e10cSrcweir { 1001cdf0e10cSrcweir HIThemeButtonDrawInfo aListInfo; 1002cdf0e10cSrcweir aListInfo.version = 0; 1003cdf0e10cSrcweir aListInfo.kind = kThemePopupButton; 1004cdf0e10cSrcweir aListInfo.state = getState( nState );//kThemeStateInactive -> greyed 1005cdf0e10cSrcweir aListInfo.value = kThemeButtonOn; 1006cdf0e10cSrcweir 1007cdf0e10cSrcweir aListInfo.adornment = kThemeAdornmentDefault; 1008cdf0e10cSrcweir if( (nState & CTRL_STATE_FOCUSED) != 0 ) 1009cdf0e10cSrcweir aListInfo.adornment |= kThemeAdornmentFocus; 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir HIThemeDrawButton(&rc, &aListInfo, mrContext, kHIThemeOrientationNormal,&rc); 1012cdf0e10cSrcweir bOK = true; 1013cdf0e10cSrcweir break; 1014cdf0e10cSrcweir } 1015cdf0e10cSrcweir case PART_WINDOW: 1016cdf0e10cSrcweir { 1017cdf0e10cSrcweir HIThemeFrameDrawInfo aTextDrawInfo; 1018cdf0e10cSrcweir aTextDrawInfo.version=0; 1019cdf0e10cSrcweir aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare; 1020cdf0e10cSrcweir aTextDrawInfo.state=getState( nState ); 1021cdf0e10cSrcweir aTextDrawInfo.isFocused=false; 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir rc.size.width+=1;//else there's a white space because aqua theme hasn't a 3D border 1024cdf0e10cSrcweir rc.size.height+=1; 1025cdf0e10cSrcweir HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal); 1026cdf0e10cSrcweir 1027cdf0e10cSrcweir if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal); 1028cdf0e10cSrcweir 1029cdf0e10cSrcweir bOK=true; 1030cdf0e10cSrcweir break; 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir } 1033cdf0e10cSrcweir break; 1034cdf0e10cSrcweir 1035cdf0e10cSrcweir case CTRL_EDITBOX: 1036cdf0e10cSrcweir case CTRL_MULTILINE_EDITBOX: 1037cdf0e10cSrcweir { 1038cdf0e10cSrcweir HIThemeFrameDrawInfo aTextDrawInfo; 1039cdf0e10cSrcweir aTextDrawInfo.version=0; 1040cdf0e10cSrcweir aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare; 1041cdf0e10cSrcweir aTextDrawInfo.state=getState( nState ); 1042cdf0e10cSrcweir aTextDrawInfo.isFocused=false; 1043cdf0e10cSrcweir 1044cdf0e10cSrcweir rc.size.width += 1; // else there may be a white space because aqua theme hasn't a 3D border 1045cdf0e10cSrcweir // change rc so that the frame will encompass only the content region 1046cdf0e10cSrcweir // see counterpart in GetNativeControlRegion 1047cdf0e10cSrcweir rc.size.width += 2; 1048cdf0e10cSrcweir rc.size.height += 2; 1049cdf0e10cSrcweir 1050cdf0e10cSrcweir //CGContextSetFillColorWithColor 1051cdf0e10cSrcweir CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height)); 1052cdf0e10cSrcweir //fill a white background, because drawFrame only draws the border 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal); 1055cdf0e10cSrcweir 1056cdf0e10cSrcweir if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal); 1057cdf0e10cSrcweir 1058cdf0e10cSrcweir bOK=true; 1059cdf0e10cSrcweir } 1060cdf0e10cSrcweir break; 1061cdf0e10cSrcweir 1062cdf0e10cSrcweir case CTRL_SPINBOX: 1063cdf0e10cSrcweir { 1064cdf0e10cSrcweir if(nPart == PART_ENTIRE_CONTROL) 1065cdf0e10cSrcweir { 1066cdf0e10cSrcweir //text field: 1067cdf0e10cSrcweir HIThemeFrameDrawInfo aTextDrawInfo; 1068cdf0e10cSrcweir aTextDrawInfo.version=0; 1069cdf0e10cSrcweir aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare; 1070cdf0e10cSrcweir aTextDrawInfo.state=getState( nState ); 1071cdf0e10cSrcweir aTextDrawInfo.isFocused=false; 1072cdf0e10cSrcweir 1073cdf0e10cSrcweir //rc.size.width contains the full size of the spinbox ie textfield + button 1074cdf0e10cSrcweir //so we remove the button width and the space between the button and the textfield 1075cdf0e10cSrcweir rc.size.width -= SPIN_BUTTON_SPACE + SPIN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH; 1076cdf0e10cSrcweir rc.origin.x += FOCUS_RING_WIDTH; 1077cdf0e10cSrcweir rc.origin.y += FOCUS_RING_WIDTH; 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir //CGContextSetFillColorWithColor 1080cdf0e10cSrcweir CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height)); 1081cdf0e10cSrcweir //fill a white background, because drawFrame only draws the border 1082cdf0e10cSrcweir 1083cdf0e10cSrcweir HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal); 1084cdf0e10cSrcweir 1085cdf0e10cSrcweir if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal); 1086cdf0e10cSrcweir 1087cdf0e10cSrcweir //buttons: 10883460f9c8SHerbert Dürr const SpinbuttonValue* pSpinButtonVal = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue*>(&aValue) : NULL; 1089cdf0e10cSrcweir ControlState nUpperState = CTRL_STATE_ENABLED;//state of the upper button 1090cdf0e10cSrcweir ControlState nLowerState = CTRL_STATE_ENABLED;//and of the lower button 1091cdf0e10cSrcweir if(pSpinButtonVal) {//pSpinButtonVal is sometimes null 1092cdf0e10cSrcweir nUpperState = (ControlState) pSpinButtonVal->mnUpperState; 1093cdf0e10cSrcweir nLowerState = (ControlState) pSpinButtonVal->mnLowerState; 1094cdf0e10cSrcweir 1095cdf0e10cSrcweir HIThemeButtonDrawInfo aSpinInfo; 1096cdf0e10cSrcweir aSpinInfo.kind = kThemeIncDecButton; 1097cdf0e10cSrcweir aSpinInfo.state = kThemeStateActive; 1098cdf0e10cSrcweir if(nUpperState & CTRL_STATE_PRESSED) 1099cdf0e10cSrcweir aSpinInfo.state = kThemeStatePressedUp; 1100cdf0e10cSrcweir else if(nLowerState & CTRL_STATE_PRESSED) 1101cdf0e10cSrcweir aSpinInfo.state = kThemeStatePressedDown; 1102cdf0e10cSrcweir else if((nUpperState & ~CTRL_STATE_ENABLED)||(nLowerState & ~CTRL_STATE_ENABLED)) 1103cdf0e10cSrcweir aSpinInfo.state = kThemeStateInactive; 1104cdf0e10cSrcweir else if((nUpperState & CTRL_STATE_ROLLOVER)||(nLowerState & CTRL_STATE_ROLLOVER)) 1105cdf0e10cSrcweir aSpinInfo.state = kThemeStateRollover; 1106cdf0e10cSrcweir 1107cdf0e10cSrcweir Rectangle aSpinRect( pSpinButtonVal->maUpperRect ); 1108cdf0e10cSrcweir aSpinRect.Union( pSpinButtonVal->maLowerRect ); 1109cdf0e10cSrcweir HIRect buttonRc = ImplGetHIRectFromRectangle(aSpinRect); 1110cdf0e10cSrcweir 1111cdf0e10cSrcweir // FIXME: without this fuzz factor there is some unwanted clipping 1112cdf0e10cSrcweir if( Application::GetSettings().GetLayoutRTL() ) 1113cdf0e10cSrcweir buttonRc.origin.x -= FOCUS_RING_WIDTH - CLIP_FUZZ; 1114cdf0e10cSrcweir else 1115cdf0e10cSrcweir buttonRc.origin.x += FOCUS_RING_WIDTH + CLIP_FUZZ; 1116cdf0e10cSrcweir 1117cdf0e10cSrcweir switch( aValue.getTristateVal() ) 1118cdf0e10cSrcweir { 1119cdf0e10cSrcweir case BUTTONVALUE_ON: aSpinInfo.value = kThemeButtonOn; 1120cdf0e10cSrcweir break; 1121cdf0e10cSrcweir case BUTTONVALUE_OFF: aSpinInfo.value = kThemeButtonOff; 1122cdf0e10cSrcweir break; 1123cdf0e10cSrcweir case BUTTONVALUE_MIXED: 1124cdf0e10cSrcweir case BUTTONVALUE_DONTKNOW: 1125cdf0e10cSrcweir default: aSpinInfo.value = kThemeButtonMixed; 1126cdf0e10cSrcweir break; 1127cdf0e10cSrcweir } 1128cdf0e10cSrcweir 1129cdf0e10cSrcweir aSpinInfo.adornment = ( ((nUpperState & CTRL_STATE_DEFAULT) != 0 ) || 1130cdf0e10cSrcweir ((nLowerState & CTRL_STATE_DEFAULT) != 0 )) ? 1131cdf0e10cSrcweir kThemeAdornmentDefault : 1132cdf0e10cSrcweir kThemeAdornmentNone; 1133cdf0e10cSrcweir if( ((nUpperState & CTRL_STATE_FOCUSED) != 0 ) || ((nLowerState & CTRL_STATE_FOCUSED) != 0 )) 1134cdf0e10cSrcweir aSpinInfo.adornment |= kThemeAdornmentFocus; 1135cdf0e10cSrcweir 1136cdf0e10cSrcweir HIThemeDrawButton( &buttonRc, &aSpinInfo, mrContext, kHIThemeOrientationNormal, NULL ); 1137cdf0e10cSrcweir } 1138cdf0e10cSrcweir 1139cdf0e10cSrcweir bOK=true; 1140cdf0e10cSrcweir } 1141cdf0e10cSrcweir 1142cdf0e10cSrcweir } 1143cdf0e10cSrcweir break; 1144cdf0e10cSrcweir 1145cdf0e10cSrcweir case CTRL_FRAME: 1146cdf0e10cSrcweir { 1147cdf0e10cSrcweir sal_uInt16 nStyle = aValue.getNumericVal(); 1148cdf0e10cSrcweir if( nPart == PART_BORDER ) { 1149cdf0e10cSrcweir if(!( nStyle & FRAME_DRAW_MENU ) && !(nStyle & FRAME_DRAW_WINDOWBORDER) ) 1150cdf0e10cSrcweir { 1151cdf0e10cSrcweir // #i84756# strange effects start to happen when HIThemeDrawFrame 1152cdf0e10cSrcweir // meets the border of the window. These can be avoided by clipping 1153cdf0e10cSrcweir // to the boundary of the frame 1154cdf0e10cSrcweir if( rc.origin.y + rc.size.height >= mpFrame->maGeometry.nHeight-3 ) 1155cdf0e10cSrcweir { 1156cdf0e10cSrcweir CGMutablePathRef rPath = CGPathCreateMutable(); 1157cdf0e10cSrcweir CGPathAddRect( rPath, NULL, CGRectMake( 0, 0, mpFrame->maGeometry.nWidth-1, mpFrame->maGeometry.nHeight-1 ) ); 1158cdf0e10cSrcweir 1159cdf0e10cSrcweir CGContextBeginPath( mrContext ); 1160cdf0e10cSrcweir CGContextAddPath( mrContext, rPath ); 1161cdf0e10cSrcweir CGContextClip( mrContext ); 1162cdf0e10cSrcweir CGPathRelease( rPath ); 1163cdf0e10cSrcweir } 1164cdf0e10cSrcweir 1165cdf0e10cSrcweir HIThemeFrameDrawInfo aTextDrawInfo; 1166cdf0e10cSrcweir aTextDrawInfo.version=0; 1167cdf0e10cSrcweir aTextDrawInfo.kind=kHIThemeFrameListBox; 1168cdf0e10cSrcweir aTextDrawInfo.state=kThemeStateActive; 1169cdf0e10cSrcweir aTextDrawInfo.isFocused=false; 1170cdf0e10cSrcweir 1171cdf0e10cSrcweir HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal); 1172cdf0e10cSrcweir 1173cdf0e10cSrcweir bOK=true; 1174cdf0e10cSrcweir } 1175cdf0e10cSrcweir } 1176cdf0e10cSrcweir } 1177cdf0e10cSrcweir break; 1178cdf0e10cSrcweir 1179cdf0e10cSrcweir case CTRL_LISTNET: 1180cdf0e10cSrcweir { 1181cdf0e10cSrcweir //do nothing as there isn't net for listviews on macos 1182cdf0e10cSrcweir bOK=true; 1183cdf0e10cSrcweir } 1184cdf0e10cSrcweir break; 1185cdf0e10cSrcweir 1186cdf0e10cSrcweir } 1187cdf0e10cSrcweir 1188cdf0e10cSrcweir CGContextRestoreGState( mrContext ); 1189cdf0e10cSrcweir 1190cdf0e10cSrcweir /* #i90291# in most cases invalidating the whole control region instead 1191cdf0e10cSrcweir of just the unclipped part of it is sufficient (and probably faster). 1192cdf0e10cSrcweir However for the window background we should not unnecessarily enlarge 1193cdf0e10cSrcweir the really changed rectangle since the difference is usually quite high 1194cdf0e10cSrcweir (the background is always drawn as a whole since we don't know anything 1195cdf0e10cSrcweir about its possible contents) 1196cdf0e10cSrcweir */ 1197cdf0e10cSrcweir if( nType == CTRL_WINDOW_BACKGROUND ) 1198cdf0e10cSrcweir { 1199cdf0e10cSrcweir CGRect aRect = { { 0, 0 }, { 0, 0 } }; 1200cdf0e10cSrcweir if( mxClipPath ) 1201cdf0e10cSrcweir aRect = CGPathGetBoundingBox( mxClipPath ); 1202cdf0e10cSrcweir if( aRect.size.width != 0 && aRect.size.height != 0 ) 1203cdf0e10cSrcweir buttonRect.Intersection( Rectangle( Point( static_cast<long int>(aRect.origin.x), 1204cdf0e10cSrcweir static_cast<long int>(aRect.origin.y) ), 1205cdf0e10cSrcweir Size( static_cast<long int>(aRect.size.width), 1206cdf0e10cSrcweir static_cast<long int>(aRect.size.height) ) ) ); 1207cdf0e10cSrcweir } 1208cdf0e10cSrcweir 1209cdf0e10cSrcweir RefreshRect( buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight() ); 1210cdf0e10cSrcweir 1211cdf0e10cSrcweir return bOK; 1212cdf0e10cSrcweir } 1213cdf0e10cSrcweir 1214cdf0e10cSrcweir /* 1215cdf0e10cSrcweir * DrawNativeControlText() 1216cdf0e10cSrcweir * 1217cdf0e10cSrcweir * OPTIONAL. Draws the requested text for the control described by nPart/nState. 1218cdf0e10cSrcweir * Used if text not drawn by DrawNativeControl(). 1219cdf0e10cSrcweir * 1220cdf0e10cSrcweir * rControlRegion: The bounding region of the complete control in VCL frame coordinates. 1221cdf0e10cSrcweir * aValue: An optional value (tristate/numerical/string) 1222cdf0e10cSrcweir * aCaption: A caption or title string (like button text etc) 1223cdf0e10cSrcweir */ 1224cdf0e10cSrcweir sal_Bool AquaSalGraphics::drawNativeControlText( ControlType /*nType*/, ControlPart /*nPart*/, const Rectangle& /*rControlRegion*/, 1225cdf0e10cSrcweir ControlState /*nState*/, const ImplControlValue& /*aValue*/, 1226cdf0e10cSrcweir const rtl::OUString& ) 1227cdf0e10cSrcweir { 1228cdf0e10cSrcweir return( sal_False ); 1229cdf0e10cSrcweir } 1230cdf0e10cSrcweir 1231cdf0e10cSrcweir 1232cdf0e10cSrcweir /* 1233cdf0e10cSrcweir * GetNativeControlRegion() 1234cdf0e10cSrcweir * 1235cdf0e10cSrcweir * If the return value is sal_True, rNativeBoundingRegion 1236cdf0e10cSrcweir * contains the true bounding region covered by the control 1237cdf0e10cSrcweir * including any adornment, while rNativeContentRegion contains the area 1238cdf0e10cSrcweir * within the control that can be safely drawn into without drawing over 1239cdf0e10cSrcweir * the borders of the control. 1240cdf0e10cSrcweir * 1241cdf0e10cSrcweir * rControlRegion: The bounding region of the control in VCL frame coordinates. 1242cdf0e10cSrcweir * aValue: An optional value (tristate/numerical/string) 1243cdf0e10cSrcweir * aCaption: A caption or title string (like button text etc) 1244cdf0e10cSrcweir */ 1245cdf0e10cSrcweir sal_Bool AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState /*nState*/, 1246cdf0e10cSrcweir const ImplControlValue& aValue, const rtl::OUString&, 1247cdf0e10cSrcweir Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ) 1248cdf0e10cSrcweir 1249cdf0e10cSrcweir { 1250cdf0e10cSrcweir sal_Bool toReturn = sal_False; 1251cdf0e10cSrcweir 1252cdf0e10cSrcweir Rectangle aCtrlBoundRect( rControlRegion ); 1253cdf0e10cSrcweir short x = aCtrlBoundRect.Left(); 1254cdf0e10cSrcweir short y = aCtrlBoundRect.Top(); 1255cdf0e10cSrcweir short w, h; 1256cdf0e10cSrcweir 1257cdf0e10cSrcweir sal_uInt8 nBorderCleanup = 0; 1258cdf0e10cSrcweir 1259cdf0e10cSrcweir switch (nType) 1260cdf0e10cSrcweir { 1261cdf0e10cSrcweir case CTRL_SLIDER: 1262cdf0e10cSrcweir { 1263cdf0e10cSrcweir if( nPart == PART_THUMB_HORZ ) 1264cdf0e10cSrcweir { 1265cdf0e10cSrcweir w = 19; // taken from HIG 1266cdf0e10cSrcweir h = aCtrlBoundRect.GetHeight(); 1267cdf0e10cSrcweir rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1268cdf0e10cSrcweir toReturn = true; 1269cdf0e10cSrcweir } 1270cdf0e10cSrcweir else if( nPart == PART_THUMB_VERT ) 1271cdf0e10cSrcweir { 1272cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1273cdf0e10cSrcweir h = 18; // taken from HIG 1274cdf0e10cSrcweir rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1275cdf0e10cSrcweir toReturn = true; 1276cdf0e10cSrcweir } 1277cdf0e10cSrcweir } 1278cdf0e10cSrcweir break; 1279cdf0e10cSrcweir 1280cdf0e10cSrcweir case CTRL_SCROLLBAR: 1281cdf0e10cSrcweir { 1282cdf0e10cSrcweir Rectangle aRect; 1283cdf0e10cSrcweir if( AquaGetScrollRect( /* m_nScreen */ nPart, aCtrlBoundRect, aRect ) ) 1284cdf0e10cSrcweir { 1285cdf0e10cSrcweir toReturn = sal_True; 1286cdf0e10cSrcweir rNativeBoundingRegion = aRect; 1287cdf0e10cSrcweir rNativeContentRegion = aRect; 1288cdf0e10cSrcweir } 1289cdf0e10cSrcweir } 1290cdf0e10cSrcweir break; 1291cdf0e10cSrcweir 1292cdf0e10cSrcweir case CTRL_PUSHBUTTON: 1293cdf0e10cSrcweir case CTRL_RADIOBUTTON: 1294cdf0e10cSrcweir case CTRL_CHECKBOX: 1295cdf0e10cSrcweir { 1296cdf0e10cSrcweir if ( nType == CTRL_PUSHBUTTON ) 1297cdf0e10cSrcweir { 1298cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1299cdf0e10cSrcweir h = aCtrlBoundRect.GetHeight(); 1300cdf0e10cSrcweir } 1301cdf0e10cSrcweir else 1302cdf0e10cSrcweir { 1303cdf0e10cSrcweir // checkbox and radio borders need cleanup after unchecking them 1304cdf0e10cSrcweir nBorderCleanup = 4; 1305cdf0e10cSrcweir 1306cdf0e10cSrcweir // TEXT_SEPARATOR to respect Aqua HIG 1307cdf0e10cSrcweir w = BUTTON_WIDTH + TEXT_SEPARATOR; 1308cdf0e10cSrcweir h = BUTTON_HEIGHT; 1309cdf0e10cSrcweir 1310cdf0e10cSrcweir } 1311cdf0e10cSrcweir 1312cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h + nBorderCleanup) ); 1313cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1314cdf0e10cSrcweir 1315cdf0e10cSrcweir toReturn = sal_True; 1316cdf0e10cSrcweir } 1317cdf0e10cSrcweir break; 1318cdf0e10cSrcweir case CTRL_PROGRESS: 1319cdf0e10cSrcweir { 1320cdf0e10cSrcweir Rectangle aRect( aCtrlBoundRect ); 1321cdf0e10cSrcweir if( aRect.GetHeight() < 16 ) 1322cdf0e10cSrcweir aRect.Bottom() = aRect.Top() + 9; // values taken from HIG for medium progress 1323cdf0e10cSrcweir else 1324cdf0e10cSrcweir aRect.Bottom() = aRect.Top() + 15; // values taken from HIG for large progress 1325cdf0e10cSrcweir rNativeBoundingRegion = aRect; 1326cdf0e10cSrcweir rNativeContentRegion = aRect; 1327cdf0e10cSrcweir toReturn = sal_True; 1328cdf0e10cSrcweir } 1329cdf0e10cSrcweir break; 1330cdf0e10cSrcweir 1331cdf0e10cSrcweir case CTRL_INTROPROGRESS: 1332cdf0e10cSrcweir { 1333cdf0e10cSrcweir Rectangle aRect( aCtrlBoundRect ); 1334cdf0e10cSrcweir aRect.Bottom() = aRect.Top() + INTRO_PROGRESS_HEIGHT; // values taken from HIG for medium progress 1335cdf0e10cSrcweir rNativeBoundingRegion = aRect; 1336cdf0e10cSrcweir rNativeContentRegion = aRect; 1337cdf0e10cSrcweir toReturn = sal_True; 1338cdf0e10cSrcweir } 1339cdf0e10cSrcweir break; 1340cdf0e10cSrcweir 1341cdf0e10cSrcweir case CTRL_TAB_ITEM: 1342cdf0e10cSrcweir 1343cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET; 1344cdf0e10cSrcweir 1345cdf0e10cSrcweir #ifdef OLD_TAB_STYLE 1346cdf0e10cSrcweir h = TAB_HEIGHT_NORMAL; 1347cdf0e10cSrcweir #else 1348cdf0e10cSrcweir h = TAB_HEIGHT_NORMAL+2; 1349cdf0e10cSrcweir #endif 1350cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1351cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1352cdf0e10cSrcweir 1353cdf0e10cSrcweir toReturn = sal_True; 1354cdf0e10cSrcweir 1355cdf0e10cSrcweir break; 1356cdf0e10cSrcweir 1357cdf0e10cSrcweir case CTRL_EDITBOX: 1358cdf0e10cSrcweir { 1359cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1360cdf0e10cSrcweir if( w < 3+2*FOCUS_RING_WIDTH ) 1361cdf0e10cSrcweir w = 3+2*FOCUS_RING_WIDTH; 1362cdf0e10cSrcweir h = TEXT_EDIT_HEIGHT_NORMAL+2*FOCUS_RING_WIDTH; 1363cdf0e10cSrcweir if( h < aCtrlBoundRect.GetHeight() ) 1364cdf0e10cSrcweir h = aCtrlBoundRect.GetHeight(); 1365cdf0e10cSrcweir 1366cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*(FOCUS_RING_WIDTH+1), h-2*(FOCUS_RING_WIDTH+1) ) ); 1367cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1368cdf0e10cSrcweir 1369cdf0e10cSrcweir toReturn = sal_True; 1370cdf0e10cSrcweir } 1371cdf0e10cSrcweir break; 1372cdf0e10cSrcweir case CTRL_LISTBOX: 1373cdf0e10cSrcweir case CTRL_COMBOBOX: 1374cdf0e10cSrcweir { 1375cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) 1376cdf0e10cSrcweir { 1377cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1378cdf0e10cSrcweir h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height 1379cdf0e10cSrcweir 1380cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*FOCUS_RING_WIDTH, h ) ); 1381cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) ); 1382cdf0e10cSrcweir 1383cdf0e10cSrcweir toReturn = sal_True; 1384cdf0e10cSrcweir } 1385cdf0e10cSrcweir else if( nPart == PART_BUTTON_DOWN ) 1386cdf0e10cSrcweir { 1387cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1388cdf0e10cSrcweir if( w < 3+2*FOCUS_RING_WIDTH ) 1389cdf0e10cSrcweir w = 3+2*FOCUS_RING_WIDTH; 1390cdf0e10cSrcweir h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height 1391cdf0e10cSrcweir 1392cdf0e10cSrcweir x += w-DROPDOWN_BUTTON_WIDTH - FOCUS_RING_WIDTH; 1393cdf0e10cSrcweir y += FOCUS_RING_WIDTH; 1394cdf0e10cSrcweir w = DROPDOWN_BUTTON_WIDTH; 1395cdf0e10cSrcweir 1396cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1397cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) ); 1398cdf0e10cSrcweir 1399cdf0e10cSrcweir toReturn = true; 1400cdf0e10cSrcweir } 1401cdf0e10cSrcweir else if( nPart == PART_SUB_EDIT ) 1402cdf0e10cSrcweir { 1403cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1404cdf0e10cSrcweir h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height 1405cdf0e10cSrcweir 1406cdf0e10cSrcweir x += FOCUS_RING_WIDTH; 1407cdf0e10cSrcweir x += 3; // add an offset for rounded borders 1408cdf0e10cSrcweir y += 2; // don't draw into upper border 1409cdf0e10cSrcweir y += FOCUS_RING_WIDTH; 1410cdf0e10cSrcweir w -= 3 + DROPDOWN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH; 1411cdf0e10cSrcweir if( nType == CTRL_LISTBOX ) 1412cdf0e10cSrcweir w -= 9; // HIG specifies 9 units distance between dropdown button area and content 1413cdf0e10cSrcweir h -= 4; // don't draw into lower border 1414cdf0e10cSrcweir 1415cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1416cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) ); 1417cdf0e10cSrcweir 1418cdf0e10cSrcweir toReturn = true; 1419cdf0e10cSrcweir } 1420cdf0e10cSrcweir } 1421cdf0e10cSrcweir break; 1422cdf0e10cSrcweir case CTRL_SPINBOX: 1423cdf0e10cSrcweir if( nPart == PART_ENTIRE_CONTROL ) { 1424cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth(); 1425cdf0e10cSrcweir if( w < 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH ) 1426cdf0e10cSrcweir w = 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH; 1427cdf0e10cSrcweir h = TEXT_EDIT_HEIGHT_NORMAL; 1428cdf0e10cSrcweir 1429cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y ), Size( w-2*FOCUS_RING_WIDTH, h ) ); 1430cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) ); 1431cdf0e10cSrcweir 1432cdf0e10cSrcweir toReturn = sal_True; 1433cdf0e10cSrcweir } 1434cdf0e10cSrcweir else if( nPart == PART_SUB_EDIT ) { 1435cdf0e10cSrcweir w = aCtrlBoundRect.GetWidth() - SPIN_BUTTON_SPACE - SPIN_BUTTON_WIDTH; 1436cdf0e10cSrcweir h = TEXT_EDIT_HEIGHT_NORMAL; 1437cdf0e10cSrcweir x += 4; // add an offset for rounded borders 1438cdf0e10cSrcweir y += 2; // don't draw into upper border 1439cdf0e10cSrcweir w -= 8; // offset for left and right rounded border 1440cdf0e10cSrcweir h -= 4; // don't draw into upper or ower border 1441cdf0e10cSrcweir 1442cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x + FOCUS_RING_WIDTH, y + FOCUS_RING_WIDTH ), Size( w - 2* FOCUS_RING_WIDTH, h ) ); 1443cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) ); 1444cdf0e10cSrcweir 1445cdf0e10cSrcweir toReturn = sal_True; 1446cdf0e10cSrcweir } 1447cdf0e10cSrcweir else if( nPart == PART_BUTTON_UP ) { 1448cdf0e10cSrcweir //aCtrlBoundRect.GetWidth() contains the width of the full control 1449cdf0e10cSrcweir //ie the width of the textfield + button 1450cdf0e10cSrcweir //x is the position of the left corner of the full control 1451cdf0e10cSrcweir x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; 1452cdf0e10cSrcweir y += FOCUS_RING_WIDTH - CLIP_FUZZ; 1453cdf0e10cSrcweir w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ; 1454cdf0e10cSrcweir h = SPIN_UPPER_BUTTON_HEIGHT + 2*CLIP_FUZZ; 1455cdf0e10cSrcweir 1456cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1457cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1458cdf0e10cSrcweir 1459cdf0e10cSrcweir toReturn = sal_True; 1460cdf0e10cSrcweir } 1461cdf0e10cSrcweir else if( nPart == PART_BUTTON_DOWN ) { 1462cdf0e10cSrcweir x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ; 1463cdf0e10cSrcweir y += SPIN_UPPER_BUTTON_HEIGHT + FOCUS_RING_WIDTH - CLIP_FUZZ; 1464cdf0e10cSrcweir w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ; 1465cdf0e10cSrcweir h = SPIN_LOWER_BUTTON_HEIGHT + 2*CLIP_FUZZ; 1466cdf0e10cSrcweir 1467cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1468cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1469cdf0e10cSrcweir 1470cdf0e10cSrcweir toReturn = sal_True; 1471cdf0e10cSrcweir } 1472cdf0e10cSrcweir break; 1473cdf0e10cSrcweir case CTRL_FRAME: 1474cdf0e10cSrcweir { 1475cdf0e10cSrcweir sal_uInt16 nStyle = aValue.getNumericVal(); 1476cdf0e10cSrcweir if( ( nPart == PART_BORDER ) && 1477cdf0e10cSrcweir !( nStyle & (FRAME_DRAW_MENU | FRAME_DRAW_WINDOWBORDER | FRAME_DRAW_BORDERWINDOWBORDER) ) ) 1478cdf0e10cSrcweir { 1479cdf0e10cSrcweir Rectangle aRect(aCtrlBoundRect); 1480cdf0e10cSrcweir if( nStyle & FRAME_DRAW_DOUBLEIN ) 1481cdf0e10cSrcweir { 1482cdf0e10cSrcweir aRect.Left() += 1; 1483cdf0e10cSrcweir aRect.Top() += 1; 1484cdf0e10cSrcweir //rRect.Right() -= 1; 1485cdf0e10cSrcweir //rRect.Bottom() -= 1; 1486cdf0e10cSrcweir } 1487cdf0e10cSrcweir else 1488cdf0e10cSrcweir { 1489cdf0e10cSrcweir aRect.Left() += 1; 1490cdf0e10cSrcweir aRect.Top() += 1; 1491cdf0e10cSrcweir aRect.Right() -= 1; 1492cdf0e10cSrcweir aRect.Bottom() -= 1; 1493cdf0e10cSrcweir } 1494cdf0e10cSrcweir 1495cdf0e10cSrcweir rNativeContentRegion = aRect; 1496cdf0e10cSrcweir rNativeBoundingRegion = aRect; 1497cdf0e10cSrcweir 1498cdf0e10cSrcweir toReturn = sal_True; 1499cdf0e10cSrcweir } 1500cdf0e10cSrcweir } 1501cdf0e10cSrcweir break; 1502cdf0e10cSrcweir 1503cdf0e10cSrcweir case CTRL_MENUBAR: 1504cdf0e10cSrcweir case CTRL_MENU_POPUP: 1505cdf0e10cSrcweir { 1506cdf0e10cSrcweir if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) { 1507cdf0e10cSrcweir 1508cdf0e10cSrcweir w=10; 1509cdf0e10cSrcweir h=10;//dimensions of the mark (10px font) 1510cdf0e10cSrcweir 1511cdf0e10cSrcweir rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1512cdf0e10cSrcweir rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); 1513cdf0e10cSrcweir 1514cdf0e10cSrcweir toReturn = sal_True; 1515cdf0e10cSrcweir } 1516cdf0e10cSrcweir } 1517cdf0e10cSrcweir break; 1518cdf0e10cSrcweir 1519cdf0e10cSrcweir } 1520cdf0e10cSrcweir 1521cdf0e10cSrcweir return toReturn; 1522cdf0e10cSrcweir } 1523