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