diff options
Diffstat (limited to 'vcl/ios/source/window/salframe.cxx')
-rw-r--r-- | vcl/ios/source/window/salframe.cxx | 1151 |
1 files changed, 1151 insertions, 0 deletions
diff --git a/vcl/ios/source/window/salframe.cxx b/vcl/ios/source/window/salframe.cxx new file mode 100644 index 000000000000..e18d242c59b4 --- /dev/null +++ b/vcl/ios/source/window/salframe.cxx @@ -0,0 +1,1151 @@ +/* -*- 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <string> + +#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<IosSalFrame*>(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<int>(aVisibleRect.origin.x + aVisibleRect.size.width / 10); + maGeometry.nY = static_cast<int>(aVisibleRect.origin.y + aVisibleRect.size.height / 10); + maGeometry.nWidth = static_cast<unsigned int>(aVisibleRect.size.width * 0.8); + maGeometry.nHeight = static_cast<unsigned int>(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<int>(aVisibleRect.origin.x); + maGeometry.nY = static_cast<int>(aVisibleRect.origin.y); + maGeometry.nWidth = static_cast<int>(aVisibleRect.size.width); + maGeometry.nHeight = static_cast<int>(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<long int>( 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<long>(aRect.origin.x); + rRect.nTop = static_cast<long>(aRect.origin.y); + rRect.nRight = static_cast<long>(aRect.origin.x + aRect.size.width - 1); + rRect.nBottom = static_cast<long>(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<int>(aContentRect.origin.x); + maGeometry.nY = static_cast<int>(aContentRect.origin.y); + + maGeometry.nLeftDecoration = static_cast<unsigned int>(aContentRect.origin.x - aFrameRect.origin.x); + maGeometry.nRightDecoration = static_cast<unsigned int>((aFrameRect.origin.x + aFrameRect.size.width) - + (aContentRect.origin.x + aContentRect.size.width)); + + maGeometry.nTopDecoration = static_cast<unsigned int>(aContentRect.origin.y - aFrameRect.origin.y); + maGeometry.nBottomDecoration = static_cast<unsigned int>((aFrameRect.origin.y + aFrameRect.size.height) - + (aContentRect.origin.y + aContentRect.size.height)); + + maGeometry.nWidth = static_cast<unsigned int>(aContentRect.size.width); + maGeometry.nHeight = static_cast<unsigned int>(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<CGRect> 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: */ |