/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #include #include "rtl/ustrbuf.hxx" #include "osl/file.h" #include "vcl/svapp.hxx" #include "vcl/window.hxx" #include "vcl/timer.hxx" #include "ios/saldata.hxx" #include "ios/salgdi.h" #include "ios/salframe.h" #include "ios/salmenu.h" #include "ios/saltimer.h" #include "ios/salinst.h" #include "ios/salframeview.h" #include "salwtype.hxx" using namespace std; // ======================================================================= IosSalFrame* IosSalFrame::s_pCaptureFrame = NULL; // ======================================================================= IosSalFrame::IosSalFrame( SalFrame* pParent, sal_uLong salFrameStyle ) : mpWindow(nil), mpView(nil), mpGraphics(NULL), mpParent(NULL), mnMinWidth(0), mnMinHeight(0), mnMaxWidth(0), mnMaxHeight(0), mbGraphics(false), mbShown(false), mbInitShow(true), mbPresentation( false ), mnStyle( salFrameStyle ), mnStyleMask( 0 ), mnLastEventTime( 0 ), mnLastModifierFlags( 0 ), mpMenu( NULL ), mnExtStyle( 0 ), mePointerStyle( POINTER_ARROW ), mrClippingPath( 0 ), mnICOptions( 0 ) { maSysData.nSize = sizeof( SystemEnvData ); mpParent = dynamic_cast(pParent); initWindowAndView(); SalData* pSalData = GetSalData(); pSalData->maFrames.push_front( this ); pSalData->maFrameCheck.insert( this ); } // ----------------------------------------------------------------------- IosSalFrame::~IosSalFrame() { // cleanup clipping stuff ResetClipRegion(); SalData* pSalData = GetSalData(); pSalData->maFrames.remove( this ); pSalData->maFrameCheck.erase( this ); DBG_ASSERT( this != s_pCaptureFrame, "capture frame destroyed" ); if( this == s_pCaptureFrame ) s_pCaptureFrame = NULL; if ( mpGraphics ) delete mpGraphics; if ( mpView ) { [mpView release]; } if ( mpWindow ) [mpWindow release]; } // ----------------------------------------------------------------------- void IosSalFrame::initWindowAndView() { // initialize mirroring parameters // FIXME: screens changing UIScreen * pScreen = [mpWindow screen]; if( pScreen == nil ) pScreen = [UIScreen mainScreen]; maScreenRect = [pScreen applicationFrame]; // calculate some default geometry CGRect aVisibleRect = [pScreen applicationFrame]; CocoaTouchToVCL( aVisibleRect ); maGeometry.nX = static_cast(aVisibleRect.origin.x + aVisibleRect.size.width / 10); maGeometry.nY = static_cast(aVisibleRect.origin.y + aVisibleRect.size.height / 10); maGeometry.nWidth = static_cast(aVisibleRect.size.width * 0.8); maGeometry.nHeight = static_cast(aVisibleRect.size.height * 0.8); // calculate style mask if( (mnStyle & SAL_FRAME_STYLE_FLOAT) || (mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) ; else if( mnStyle & SAL_FRAME_STYLE_DEFAULT ) { // make default window "maximized" maGeometry.nX = static_cast(aVisibleRect.origin.x); maGeometry.nY = static_cast(aVisibleRect.origin.y); maGeometry.nWidth = static_cast(aVisibleRect.size.width); maGeometry.nHeight = static_cast(aVisibleRect.size.height); } else { if( (mnStyle & SAL_FRAME_STYLE_MOVEABLE) ) { } } mpWindow = [[SalFrameWindow alloc] initWithSalFrame: this]; mpView = [[SalFrameView alloc] initWithSalFrame: this]; maSysData.pView = mpView; UpdateFrameGeometry(); } // ----------------------------------------------------------------------- void IosSalFrame::CocoaTouchToVCL( CGRect& io_rRect, bool bRelativeToScreen ) { if( bRelativeToScreen ) io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height); else io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height); } void IosSalFrame::VCLToCocoaTouch( CGRect& io_rRect, bool bRelativeToScreen ) { if( bRelativeToScreen ) io_rRect.origin.y = maScreenRect.size.height - (io_rRect.origin.y+io_rRect.size.height); else io_rRect.origin.y = maGeometry.nHeight - (io_rRect.origin.y+io_rRect.size.height); } void IosSalFrame::CocoaTouchToVCL( CGPoint& io_rPoint, bool bRelativeToScreen ) { if( bRelativeToScreen ) io_rPoint.y = maScreenRect.size.height - io_rPoint.y; else io_rPoint.y = maGeometry.nHeight - io_rPoint.y; } void IosSalFrame::VCLToCocoaTouch( CGPoint& io_rPoint, bool bRelativeToScreen ) { if( bRelativeToScreen ) io_rPoint.y = maScreenRect.size.height - io_rPoint.y; else io_rPoint.y = maGeometry.nHeight - io_rPoint.y; } // ----------------------------------------------------------------------- void IosSalFrame::screenParametersChanged() { UpdateFrameGeometry(); if( mpGraphics ) mpGraphics->updateResolution(); CallCallback( SALEVENT_DISPLAYCHANGED, 0 ); } // ----------------------------------------------------------------------- SalGraphics* IosSalFrame::GetGraphics() { if ( mbGraphics ) return NULL; if ( !mpGraphics ) { mpGraphics = new IosSalGraphics; mpGraphics->SetWindowGraphics( this ); } mbGraphics = TRUE; return mpGraphics; } // ----------------------------------------------------------------------- void IosSalFrame::ReleaseGraphics( SalGraphics *pGraphics ) { (void)pGraphics; DBG_ASSERT( pGraphics == mpGraphics, "graphics released on wrong frame" ); mbGraphics = FALSE; } // ----------------------------------------------------------------------- sal_Bool IosSalFrame::PostEvent( void *pData ) { GetSalData()->mpFirstInstance->PostUserEvent( this, SALEVENT_USEREVENT, pData ); return TRUE; } // ----------------------------------------------------------------------- void IosSalFrame::SetTitle(const XubString& /* rTitle */) { } // ----------------------------------------------------------------------- void IosSalFrame::SetIcon( sal_uInt16 ) { } // ----------------------------------------------------------------------- void IosSalFrame::SetRepresentedURL( const rtl::OUString& /* i_rDocURL */ ) { } // ----------------------------------------------------------------------- void IosSalFrame::initShow() { mbInitShow = false; { Rectangle aScreenRect; GetWorkArea( aScreenRect ); if( mpParent ) // center relative to parent { // center on parent long nNewX = mpParent->maGeometry.nX + ((long)mpParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2; if( nNewX < aScreenRect.Left() ) nNewX = aScreenRect.Left(); if( long(nNewX + maGeometry.nWidth) > aScreenRect.Right() ) nNewX = aScreenRect.Right() - maGeometry.nWidth-1; long nNewY = mpParent->maGeometry.nY + ((long)mpParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2; if( nNewY < aScreenRect.Top() ) nNewY = aScreenRect.Top(); if( nNewY > aScreenRect.Bottom() ) nNewY = aScreenRect.Bottom() - maGeometry.nHeight-1; SetPosSize( nNewX - mpParent->maGeometry.nX, nNewY - mpParent->maGeometry.nY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); } else if( ! (mnStyle & SAL_FRAME_STYLE_SIZEABLE) ) { // center on screen long nNewX = (aScreenRect.GetWidth() - maGeometry.nWidth)/2; long nNewY = (aScreenRect.GetHeight() - maGeometry.nHeight)/2; SetPosSize( nNewX, nNewY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); } } } void IosSalFrame::SendPaintEvent( const Rectangle* pRect ) { SalPaintEvent aPaintEvt( 0, 0, maGeometry.nWidth, maGeometry.nHeight, true ); if( pRect ) { aPaintEvt.mnBoundX = pRect->Left(); aPaintEvt.mnBoundY = pRect->Top(); aPaintEvt.mnBoundWidth = pRect->GetWidth(); aPaintEvt.mnBoundHeight = pRect->GetHeight(); } CallCallback(SALEVENT_PAINT, &aPaintEvt); } // ----------------------------------------------------------------------- void IosSalFrame::Show(sal_Bool bVisible, sal_Bool bNoActivate) { if ( !mpWindow ) return; // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); mbShown = bVisible; if(bVisible) { if( mbInitShow ) initShow(); CallCallback(SALEVENT_RESIZE, 0); // trigger filling our backbuffer SendPaintEvent(); if( !bNoActivate ) [mpWindow makeKeyAndVisible]; #if 0 // ??? if( mpParent ) { /* #i92674# #i96433# we do not want an invisible parent to show up (which adding a visible child implicitly does). However we also do not want a parentless toolbar. HACK: try to decide when we should not insert a child to its parent floaters and ownerdraw windows have not yet shown up in cases where we don't want the parent to become visible */ if( mpParent->mbShown || (mnStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_FLOAT) ) ) { [mpParent->mpWindow addChildWindow: mpWindow]; } } if( mbPresentation ) [mpWindow makeMainWindow]; #endif } else { #if 0 // ??? if( mpParent && [mpWindow parentWindow] == mpParent->mpWindow ) [mpParent->mpWindow removeChildWindow: mpWindow]; #endif } } // ----------------------------------------------------------------------- void IosSalFrame::Enable( sal_Bool ) { } // ----------------------------------------------------------------------- void IosSalFrame::SetMinClientSize( long nWidth, long nHeight ) { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); mnMinWidth = nWidth; mnMinHeight = nHeight; if( mpWindow ) { // Always add the decoration as the dimension concerns only // the content rectangle nWidth += maGeometry.nLeftDecoration + maGeometry.nRightDecoration; nHeight += maGeometry.nTopDecoration + maGeometry.nBottomDecoration; CGSize aSize = { nWidth, nHeight }; #if 0 // ??? // Size of full window (content+structure) although we only // have the client size in arguments [mpWindow setMinSize: aSize]; #endif } } // ----------------------------------------------------------------------- void IosSalFrame::SetMaxClientSize( long nWidth, long nHeight ) { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); mnMaxWidth = nWidth; mnMaxHeight = nHeight; if( mpWindow ) { // Always add the decoration as the dimension concerns only // the content rectangle nWidth += maGeometry.nLeftDecoration + maGeometry.nRightDecoration; nHeight += maGeometry.nTopDecoration + maGeometry.nBottomDecoration; // Carbon windows can't have a size greater than 32767x32767 if (nWidth>32767) nWidth=32767; if (nHeight>32767) nHeight=32767; CGSize aSize = { nWidth, nHeight }; #if 0 // ??? // Size of full window (content+structure) although we only // have the client size in arguments [mpWindow setMaxSize: aSize]; #endif } } // ----------------------------------------------------------------------- void IosSalFrame::SetClientSize( long nWidth, long nHeight ) { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); if( mpWindow ) { CGSize aSize = { nWidth, nHeight }; #if 0 // ??? [mpWindow setContentSize: aSize]; #endif UpdateFrameGeometry(); if( mbShown ) // trigger filling our backbuffer SendPaintEvent(); } } // ----------------------------------------------------------------------- void IosSalFrame::GetClientSize( long& rWidth, long& rHeight ) { if( mbShown || mbInitShow ) { rWidth = maGeometry.nWidth; rHeight = maGeometry.nHeight; } else { rWidth = 0; rHeight = 0; } } // ----------------------------------------------------------------------- void IosSalFrame::SetWindowState( const SalFrameState* pState ) { // ??? // get new geometry UpdateFrameGeometry(); sal_uInt16 nEvent = 0; if( pState->mnMask & (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_X) ) { mbPositioned = true; nEvent = SALEVENT_MOVE; } if( pState->mnMask & (SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT) ) { mbSized = true; nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; } // send event that we were moved/sized if( nEvent ) CallCallback( nEvent, NULL ); if( mbShown && mpWindow ) { // trigger filling our backbuffer SendPaintEvent(); } } // ----------------------------------------------------------------------- sal_Bool IosSalFrame::GetWindowState( SalFrameState* pState ) { if ( !mpWindow ) return FALSE; // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); pState->mnMask = SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT | SAL_FRAMESTATE_MASK_STATE; CGRect aStateRect = [mpWindow frame]; #if 0 // ??? aStateRect = [UIWindow contentRectForFrameRect: aStateRect styleMask: mnStyleMask]; CocoaTouchToVCL( aStateRect ); pState->mnX = long(aStateRect.origin.x); pState->mnY = long(aStateRect.origin.y); pState->mnWidth = long(aStateRect.size.width); pState->mnHeight = long(aStateRect.size.height); #endif pState->mnState = SAL_FRAMESTATE_MAXIMIZED; return TRUE; } // ----------------------------------------------------------------------- void IosSalFrame::SetScreenNumber(unsigned int nScreen) { // ??? } void IosSalFrame::SetApplicationID( const rtl::OUString &/*rApplicationID*/ ) { } // ----------------------------------------------------------------------- void IosSalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay ) { // ??? } // ----------------------------------------------------------------------- void IosSalFrame::StartPresentation( sal_Bool bStart ) { if ( !mpWindow ) return; // ??? } // ----------------------------------------------------------------------- void IosSalFrame::SetAlwaysOnTop( sal_Bool ) { } // ----------------------------------------------------------------------- void IosSalFrame::ToTop(sal_uInt16 nFlags) { if ( !mpWindow ) return; // ??? } // ----------------------------------------------------------------------- void IosSalFrame::SetPointer( PointerStyle ePointerStyle ) { } // ----------------------------------------------------------------------- void IosSalFrame::SetPointerPos( long /* nX */ , long /* nY */ ) { } // ----------------------------------------------------------------------- void IosSalFrame::Flush( void ) { // ??? } // ----------------------------------------------------------------------- void IosSalFrame::Flush( const Rectangle& rRect ) { // ??? } // ----------------------------------------------------------------------- void IosSalFrame::Sync() { // ??? } // ----------------------------------------------------------------------- void IosSalFrame::SetInputContext( SalInputContext* pContext ) { if (!pContext) { mnICOptions = 0; return; } mnICOptions = pContext->mnOptions; if(!(pContext->mnOptions & SAL_INPUTCONTEXT_TEXT)) return; } // ----------------------------------------------------------------------- void IosSalFrame::EndExtTextInput( sal_uInt16 ) { } // ----------------------------------------------------------------------- XubString IosSalFrame::GetKeyName( sal_uInt16 nKeyCode ) { static std::map< sal_uInt16, rtl::OUString > aKeyMap; if( aKeyMap.empty() ) { sal_uInt16 i; for( i = KEY_A; i <= KEY_Z; i++ ) aKeyMap[ i ] = rtl::OUString( sal_Unicode( 'A' + (i - KEY_A) ) ); for( i = KEY_0; i <= KEY_9; i++ ) aKeyMap[ i ] = rtl::OUString( sal_Unicode( '0' + (i - KEY_0) ) ); for( i = KEY_F1; i <= KEY_F26; i++ ) { rtl::OUStringBuffer aKey( 3 ); aKey.append( sal_Unicode( 'F' ) ); aKey.append( sal_Int32( i - KEY_F1 + 1 ) ); aKeyMap[ i ] = aKey.makeStringAndClear(); } aKeyMap[ KEY_DOWN ] = rtl::OUString( sal_Unicode( 0x21e3 ) ); aKeyMap[ KEY_UP ] = rtl::OUString( sal_Unicode( 0x21e1 ) ); aKeyMap[ KEY_LEFT ] = rtl::OUString( sal_Unicode( 0x21e0 ) ); aKeyMap[ KEY_RIGHT ] = rtl::OUString( sal_Unicode( 0x21e2 ) ); aKeyMap[ KEY_HOME ] = rtl::OUString( sal_Unicode( 0x2196 ) ); aKeyMap[ KEY_END ] = rtl::OUString( sal_Unicode( 0x2198 ) ); aKeyMap[ KEY_PAGEUP ] = rtl::OUString( sal_Unicode( 0x21de ) ); aKeyMap[ KEY_PAGEDOWN ] = rtl::OUString( sal_Unicode( 0x21df ) ); aKeyMap[ KEY_RETURN ] = rtl::OUString( sal_Unicode( 0x21a9 ) ); aKeyMap[ KEY_ESCAPE ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "esc" ) ); aKeyMap[ KEY_TAB ] = rtl::OUString( sal_Unicode( 0x21e5 ) ); aKeyMap[ KEY_BACKSPACE ]= rtl::OUString( sal_Unicode( 0x232b ) ); aKeyMap[ KEY_SPACE ] = rtl::OUString( sal_Unicode( 0x2423 ) ); aKeyMap[ KEY_DELETE ] = rtl::OUString( sal_Unicode( 0x2326 ) ); aKeyMap[ KEY_ADD ] = rtl::OUString( sal_Unicode( '+' ) ); aKeyMap[ KEY_SUBTRACT ] = rtl::OUString( sal_Unicode( '-' ) ); aKeyMap[ KEY_DIVIDE ] = rtl::OUString( sal_Unicode( '/' ) ); aKeyMap[ KEY_MULTIPLY ] = rtl::OUString( sal_Unicode( '*' ) ); aKeyMap[ KEY_POINT ] = rtl::OUString( sal_Unicode( '.' ) ); aKeyMap[ KEY_COMMA ] = rtl::OUString( sal_Unicode( ',' ) ); aKeyMap[ KEY_LESS ] = rtl::OUString( sal_Unicode( '<' ) ); aKeyMap[ KEY_GREATER ] = rtl::OUString( sal_Unicode( '>' ) ); aKeyMap[ KEY_EQUAL ] = rtl::OUString( sal_Unicode( '=' ) ); aKeyMap[ KEY_OPEN ] = rtl::OUString( sal_Unicode( 0x23cf ) ); /* yet unmapped KEYCODES: aKeyMap[ KEY_INSERT ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_CUT ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_COPY ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_PASTE ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_UNDO ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_REPEAT ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_FIND ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_PROPERTIES ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_FRONT ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_CONTEXTMENU ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_MENU ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_HELP ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_HANGUL_HANJA ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_DECIMAL ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_TILDE ] = rtl::OUString( sal_Unicode( ) ); aKeyMap[ KEY_QUOTELEFT ]= rtl::OUString( sal_Unicode( ) ); */ } rtl::OUStringBuffer aResult( 16 ); sal_uInt16 nUnmodifiedCode = (nKeyCode & KEY_CODE); std::map< sal_uInt16, rtl::OUString >::const_iterator it = aKeyMap.find( nUnmodifiedCode ); if( it != aKeyMap.end() ) { if( (nKeyCode & KEY_SHIFT) != 0 ) aResult.append( sal_Unicode( 0x21e7 ) ); if( (nKeyCode & KEY_MOD1) != 0 ) aResult.append( sal_Unicode( 0x2318 ) ); // we do not really handle Alt (see below) // we map it to MOD3, whichis actually Command if( (nKeyCode & (KEY_MOD2|KEY_MOD3)) != 0 ) aResult.append( sal_Unicode( 0x2303 ) ); aResult.append( it->second ); } return aResult.makeStringAndClear(); } // ----------------------------------------------------------------------- XubString IosSalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode ) { return GetKeyName( nKeyCode ); } // ----------------------------------------------------------------------- void IosSalFrame::getResolution( long& o_rDPIX, long& o_rDPIY ) { if( ! mpGraphics ) { GetGraphics(); ReleaseGraphics( mpGraphics ); } mpGraphics->GetResolution( o_rDPIX, o_rDPIY ); } void IosSalFrame::UpdateSettings( AllSettings& rSettings ) { if ( !mpWindow ) return; // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); StyleSettings aStyleSettings = rSettings.GetStyleSettings(); // Background Color Color aBackgroundColor = Color( 0xEC, 0xEC, 0xEC ); aStyleSettings.Set3DColors( aBackgroundColor ); aStyleSettings.SetFaceColor( aBackgroundColor ); Color aInactiveTabColor( aBackgroundColor ); aInactiveTabColor.DecreaseLuminance( 32 ); aStyleSettings.SetInactiveTabColor( aInactiveTabColor ); aStyleSettings.SetDialogColor( aBackgroundColor ); aStyleSettings.SetLightBorderColor( aBackgroundColor ); Color aShadowColor( aStyleSettings.GetShadowColor() ); aStyleSettings.SetDarkShadowColor( aShadowColor ); aShadowColor.IncreaseLuminance( 32 ); aStyleSettings.SetShadowColor( aShadowColor ); // get the system font settings Font aAppFont = aStyleSettings.GetAppFont(); long nDPIX = 72, nDPIY = 72; getResolution( nDPIX, nDPIY ); aStyleSettings.SetToolbarIconSize( nDPIY > 160 ? STYLE_TOOLBAR_ICONSIZE_LARGE : STYLE_TOOLBAR_ICONSIZE_SMALL ); aStyleSettings.SetCursorBlinkTime( 500 ); // no mnemonics on iOs aStyleSettings.SetOptions( aStyleSettings.GetOptions() | STYLE_OPTION_NOMNEMONICS ); // images in menus false for iOS aStyleSettings.SetPreferredUseImagesInMenus( false ); aStyleSettings.SetHideDisabledMenuItems( sal_True ); aStyleSettings.SetAcceleratorsInContextMenus( sal_False ); rSettings.SetStyleSettings( aStyleSettings ); } // ----------------------------------------------------------------------- const SystemEnvData* IosSalFrame::GetSystemData() const { return &maSysData; } // ----------------------------------------------------------------------- void IosSalFrame::Beep( SoundType eSoundType ) { switch( eSoundType ) { case SOUND_DISABLE: // don't beep break; default: // ??? break; } } // ----------------------------------------------------------------------- void IosSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags) { if ( !mpWindow ) return; // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); sal_uInt16 nEvent = 0; if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) { mbPositioned = true; nEvent = SALEVENT_MOVE; } if (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) { mbSized = true; nEvent = (nEvent == SALEVENT_MOVE) ? SALEVENT_MOVERESIZE : SALEVENT_RESIZE; } CGRect aFrameRect = [mpWindow frame]; #if 0 // ??? CGRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; // position is always relative to parent frame CGRect aParentContentRect; if( mpParent ) { if( Application::GetSettings().GetLayoutRTL() ) { if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 ) nX = mpParent->maGeometry.nWidth - nWidth-1 - nX; else nX = mpParent->maGeometry.nWidth - static_cast( aContentRect.size.width-1) - nX; } CGRect aParentFrameRect = [mpParent->mpWindow frame]; aParentContentRect = [NSWindow contentRectForFrameRect: aParentFrameRect styleMask: mpParent->mnStyleMask]; } else aParentContentRect = maScreenRect; // use screen if no parent CocoaTouchToVCL( aContentRect ); CocoaTouchToVCL( aParentContentRect ); bool bPaint = false; if( (nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) != 0 ) { if( nWidth != aContentRect.size.width || nHeight != aContentRect.size.height ) bPaint = true; } // use old window pos if no new pos requested if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 ) aContentRect.origin.x = nX + aParentContentRect.origin.x; if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0) aContentRect.origin.y = nY + aParentContentRect.origin.y; // use old size if no new size requested if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 ) aContentRect.size.width = nWidth; if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0) aContentRect.size.height = nHeight; VCLToCocoaTouch( aContentRect ); // do not display yet, we need to update our backbuffer { [mpWindow setFrame: [NSWindow frameRectForContentRect: aContentRect styleMask: mnStyleMask] display: NO]; } UpdateFrameGeometry(); if (nEvent) CallCallback(nEvent, NULL); if( mbShown && bPaint ) { // trigger filling our backbuffer SendPaintEvent(); // now inform the system that the views need to be drawn [mpWindow display]; } #endif } void IosSalFrame::GetWorkArea( Rectangle& rRect ) { if ( !mpWindow ) return; // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); UIScreen* pScreen = [mpWindow screen]; if( pScreen == nil ) pScreen = [UIScreen mainScreen]; CGRect aRect = [pScreen applicationFrame]; CocoaTouchToVCL( aRect ); rRect.nLeft = static_cast(aRect.origin.x); rRect.nTop = static_cast(aRect.origin.y); rRect.nRight = static_cast(aRect.origin.x + aRect.size.width - 1); rRect.nBottom = static_cast(aRect.origin.y + aRect.size.height - 1); } SalPointerState IosSalFrame::GetPointerState() { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); SalPointerState state; state.mnState = 0; // ??? return state; } SalFrame::SalIndicatorState IosSalFrame::GetIndicatorState() { SalIndicatorState aState; aState.mnState = 0; return aState; } void IosSalFrame::SimulateKeyPress( sal_uInt16 /*nKeyCode*/ ) { } bool IosSalFrame::SetPluginParent( SystemParentData* ) { // plugin parent may be killed unexpectedly by // plugging process; //TODO: implement return sal_False; } sal_Bool IosSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& ) { // not supported yet return FALSE; } LanguageType IosSalFrame::GetInputLanguage() { //TODO: implement return LANGUAGE_DONTKNOW; } void IosSalFrame::DrawMenuBar() { } void IosSalFrame::SetMenu( SalMenu* pSalMenu ) { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); // ??? } void IosSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) { // ??? } void IosSalFrame::SetBackgroundBitmap( SalBitmap* ) { //TODO: implement } SalBitmap* IosSalFrame::SnapShot() { return mpGraphics ? mpGraphics->getBitmap( 0, 0, maGeometry.nWidth, maGeometry.nHeight ) : NULL; } SalFrame* IosSalFrame::GetParent() const { return mpParent; } void IosSalFrame::SetParent( SalFrame* pNewParent ) { bool bShown = mbShown; // remove from child list Show( FALSE ); mpParent = (IosSalFrame*)pNewParent; // insert to correct parent and paint Show( bShown ); } void IosSalFrame::UpdateFrameGeometry() { if ( !mpWindow ) { return; } // keep in mind that view and window coordinates are lower left // whereas vcl's are upper left #if 0 // ??? // update screen rect NSScreen * pScreen = [mpWindow screen]; if( pScreen ) { maScreenRect = [pScreen frame]; NSArray* pScreens = [NSScreen screens]; if( pScreens ) maGeometry.nScreenNumber = [pScreens indexOfObject: pScreen]; } CGRect aFrameRect = [mpWindow frame]; CGRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; // release old track rect [mpView removeTrackingRect: mnTrackingRectTag]; // install the new track rect CGRect aTrackRect = { { 0, 0 }, aContentRect.size }; mnTrackingRectTag = [mpView addTrackingRect: aTrackRect owner: mpView userData: nil assumeInside: NO]; // convert to vcl convention CocoaTouchToVCL( aFrameRect ); CocoaTouchToVCL( aContentRect ); maGeometry.nX = static_cast(aContentRect.origin.x); maGeometry.nY = static_cast(aContentRect.origin.y); maGeometry.nLeftDecoration = static_cast(aContentRect.origin.x - aFrameRect.origin.x); maGeometry.nRightDecoration = static_cast((aFrameRect.origin.x + aFrameRect.size.width) - (aContentRect.origin.x + aContentRect.size.width)); maGeometry.nTopDecoration = static_cast(aContentRect.origin.y - aFrameRect.origin.y); maGeometry.nBottomDecoration = static_cast((aFrameRect.origin.y + aFrameRect.size.height) - (aContentRect.origin.y + aContentRect.size.height)); maGeometry.nWidth = static_cast(aContentRect.size.width); maGeometry.nHeight = static_cast(aContentRect.size.height); #endif } // ----------------------------------------------------------------------- void IosSalFrame::CaptureMouse( sal_Bool bCapture ) { /* Remark: we'll try to use a pidgin version of capture mouse on MacOSX (neither carbon nor cocoa) there is a CaptureMouse equivalent (in Carbon there is TrackMouseLocation but this is useless to use since it is blocking) However on cocoa the active frame seems to get mouse events also outside the window, so we'll try to forward mouse events to the capture frame in the hope that one of our frames gets a mouse event. This will break as soon as the user activates another app, but a mouse click will normally lead to a release of the mouse anyway. Let's see how far we get this way. Alternatively we could use one large overlay window like we did for the carbon implementation, however that is resource intensive. */ if( bCapture ) s_pCaptureFrame = this; else if( ! bCapture && s_pCaptureFrame == this ) s_pCaptureFrame = NULL; } void IosSalFrame::ResetClipRegion() { if ( !mpWindow ) { return; } // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); // release old path and indicate no clipping CGPathRelease( mrClippingPath ); mrClippingPath = NULL; if( mpWindow ) { [mpWindow setOpaque: YES]; } } void IosSalFrame::BeginSetClipRegion( sal_uLong nRects ) { if ( !mpWindow ) { return; } // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); // release old path if( mrClippingPath ) { CGPathRelease( mrClippingPath ); mrClippingPath = NULL; } if( maClippingRects.size() > SAL_CLIPRECT_COUNT && nRects < maClippingRects.size() ) { std::vector aEmptyVec; maClippingRects.swap( aEmptyVec ); } maClippingRects.clear(); maClippingRects.reserve( nRects ); } void IosSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) { // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); if( nWidth && nHeight ) { CGRect aRect = { { nX, nY }, { nWidth, nHeight } }; VCLToCocoaTouch( aRect, false ); maClippingRects.push_back( CGRectMake(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height) ); } } void IosSalFrame::EndSetClipRegion() { if ( !mpWindow ) { return; } // #i113170# may not be the main thread if called from UNO API SalData::ensureThreadAutoreleasePool(); if( ! maClippingRects.empty() ) { mrClippingPath = CGPathCreateMutable(); CGPathAddRects( mrClippingPath, NULL, &maClippingRects[0], maClippingRects.size() ); } if( mpWindow ) { [mpWindow setOpaque: (mrClippingPath != NULL) ? NO : YES]; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */