// Panel.cpp : Implementation of cPanel #include "stdafx.h" #include "Inject.h" #include "Panel.h" #include "Manager.h" ///////////////////////////////////////////////////////////////////////////// // cPanel enum ePanelChildren { eViewFirst = 1000 }; cPanel::cPanel() : m_nActiveView( -1 ), m_bDragging( false ), m_bSizingXL( false ), m_bSizingXR( false ), m_bSizingYT( false ), m_bSizingYB( false ), m_bTransparent( false ), m_pcView( NULL ), m_Alpha( 255 ) { } void cPanel::hideView() { m_pSite->Invalidate(); if( m_nActiveView == -1 ) // No active view currently return; CComPtr< ILayerSite > pActive; m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive ); static RECT rcHide = { 0, 0, 0, 0 }; pActive->put_Position( &rcHide ); if( m_pSink.p != NULL ) m_pSink->PanelDeactivate( m_nActiveView ); m_nActiveView = -1; } void cPanel::onCreate() { CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); pPlugin->LoadBitmapPortal( 0x0600126F, &m_pBackground ); pPlugin->LoadBitmapPortal( 0x06001277, &m_pBorder ); BSTR bstrFontName; pPlugin->get_FontName(&bstrFontName); pPlugin->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 15, eFontBold, &m_pTitle ); // Create the Button CComPtr< IButton > pRollup; HRESULT hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton, reinterpret_cast< void ** >( &pRollup ) ); _ASSERTE( SUCCEEDED( hRes ) ); CComPtr< ILayer > pBtnLayer; pRollup->QueryInterface( &pBtnLayer ); LayerParams lp = { 1, { 180 - 16, 0, 180, 16 }, eRenderClipped }; m_pSite->CreateChild( &lp, pBtnLayer ); pRollup->put_Matte( RGB( 0, 0, 0 ) ); pRollup->SetImages( 0, 0x0600113C, 0x0600113B ); ICommandEventsImpl< BUTTON_CLOSE, cPanel >::advise( pRollup ); // Create the Increment Button hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton, reinterpret_cast< void ** >( &m_pButtonInc ) ); _ASSERTE( SUCCEEDED( hRes ) ); CComPtr< ILayer > pBtnIncLayer; m_pButtonInc->QueryInterface( &pBtnIncLayer ); LayerParams lpInc = { 2, { 180 - 32, 0, 180 - 32 + 16, 16 }, eRenderClipped }; m_pSite->CreateChild( &lpInc, pBtnIncLayer ); m_pButtonInc->put_Matte( RGB( 0, 0, 0 ) ); m_pButtonInc->SetImages( 0, 0x06001298, 0x06001299 ); ICommandEventsImpl< BUTTON_INC, cPanel >::advise( m_pButtonInc ); // Create the Decrement Button hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton, reinterpret_cast< void ** >( &m_pButtonDec ) ); _ASSERTE( SUCCEEDED( hRes ) ); CComPtr< ILayer > pBtnDecLayer; m_pButtonDec->QueryInterface( &pBtnDecLayer ); LayerParams lpDec = { 3, { 180 - 48, 0, 180 - 48 + 16, 16 }, eRenderClipped }; m_pSite->CreateChild( &lpDec, pBtnDecLayer ); m_pButtonDec->put_Matte( RGB( 0, 0, 0 ) ); m_pButtonDec->SetImages( 0, 0x06001295, 0x06001296 ); ICommandEventsImpl< BUTTON_DEC, cPanel >::advise( m_pButtonDec ); // Set this layer not transparent to be transparent m_pSite->put_Transparent( VARIANT_FALSE ); RegKey key; key.Create( HKEY_LOCAL_MACHINE, _T( "SOFTWARE\\Decal" ) ); if(key.QueryDWORDValue("ViewAlpha", m_Alpha) != ERROR_SUCCESS) m_Alpha = 255; } void cPanel::onDestroy() { m_pBorder.Release(); m_pBackground.Release(); m_pTitle.Release(); m_pButtonInc.Release(); m_pButtonDec.Release(); } STDMETHODIMP cPanel::Render( ICanvas *pCanvas ) { RECT rc; m_pSite->get_Position( &rc ); SIZE szBorder; m_pBorder->get_Size( &szBorder ); // Draw the background RECT rc_pat = { 0, 0, rc.right - rc.left, rc.bottom - rc.top }; static POINT pt_pat = { 0, 0 }; if( ! m_bTransparent ) m_pBackground->PatBlt( pCanvas, &rc_pat, &pt_pat ); // Draw the borders RECT rc_border_top = { 0, 0, rc.right - rc.left, szBorder.cy }, rc_border_bottom = { 0, rc.bottom - rc.top - szBorder.cy, rc.right - rc.left, rc.bottom - rc.top }; pCanvas->Fill( &rc_border_top, RGB( 0, 0, 0 ) ); m_pBorder->PatBlt( pCanvas, &rc_border_top, &pt_pat ); pCanvas->Fill( &rc_border_bottom, RGB( 0, 0, 0 ) ); m_pBorder->PatBlt( pCanvas, &rc_border_bottom, &pt_pat ); // Draw the title text if( _bstr_t(m_pVP->label).length() > 0 ) { POINT ptText = { 24, szBorder.cy + 5 }; m_pTitle->DrawText( &ptText, m_pVP->label, 0, pCanvas ); } if( m_pVP->icon != 0 ) { CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); CComPtr< IIconCache > pIconCache; static SIZE szIcon = { 16, 16 }; pPlugin->GetIconCache( &szIcon, &pIconCache ); static POINT pt = { 4, szBorder.cy + 4 }; pIconCache->DrawIcon( &pt, m_pVP->icon, m_pVP->iconLibrary, pCanvas ); } _ASSERTMEM( _CrtCheckMemory( ) ); return S_OK; } STDMETHODIMP cPanel::Reformat() { // Reset the size CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); SIZE szScreen; pPlugin->GetScreenSize( &szScreen ); RECT rc = { m_pVP->left, m_pVP->top, m_pVP->left + m_pVP->width, m_pVP->top + m_pVP->height }; m_pSite->put_Position( &rc ); RECT rcCloseBtn = { m_pVP->width - 16, 0, m_pVP->width, 16 }; CComPtr< ILayerSite > pCloseBtnLS; m_pSite->get_Child(1, ePositionByID, &pCloseBtnLS); pCloseBtnLS->put_Position(&rcCloseBtn); RECT rcIncBtn = { m_pVP->width - 32, 0, m_pVP->width - 32 + 16, 16 }; CComPtr< ILayerSite > pButtonInc; m_pSite->get_Child(2, ePositionByID, &pButtonInc); pButtonInc->put_Position( &rcIncBtn ); RECT rcDecBtn = { m_pVP->width - 48, 0, m_pVP->width - 48 + 16, 16 }; CComPtr< ILayerSite > pButtonDec; m_pSite->get_Child(3, ePositionByID, &pButtonDec); pButtonDec->put_Position( &rcDecBtn ); if( m_nActiveView != -1 ) { // Position the active view SIZE szBorder; m_pBorder->get_Size( &szBorder ); CComPtr< ILayerSite > pActive; m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive ); RECT rcChild = { 0, 24 + szBorder.cy, m_pVP->width, m_pVP->height - szBorder.cy }; pActive->put_Position( &rcChild ); } return S_OK; } STDMETHODIMP cPanel::AddView(long nViewID, ILayer *pLayer) { _ASSERTE( pLayer != NULL ); LayerParams p = { nViewID, { 0, 0, 0, 0 }, eRenderClipped }; // Set up the layer - note that it is not visible return m_pSite->CreateChild( &p, pLayer ); } STDMETHODIMP cPanel::ActivateView(long nViewID, ViewParams *pParams, long *pView) { // Hide the current view by resizing to 0,0 hideView(); m_pVP = pParams; m_pcView = (cView*)pView; VARIANT_BOOL isTransparent=VARIANT_FALSE ; if (m_pcView) m_pcView->get_Transparent(&isTransparent) ; put_Transparent(isTransparent) ; if( m_pVP->alpha == -1 ) m_pSite->put_Alpha( m_Alpha ); else m_pSite->put_Alpha( m_pVP->alpha ); #ifdef _DEBUG // Make sure the child exists CComPtr< ILayerSite > pChildSite; _ASSERTE( SUCCEEDED( m_pSite->get_Child( nViewID, ePositionByID, &pChildSite ) ) ); #endif // Locate the child m_nActiveView = nViewID; // Trick it into reformatting next frame static RECT rcBig = { 0, 0, 1, 1 }; m_pSite->put_Position( &rcBig ); // Pop us to the front m_pSite->moveToFront(); return S_OK; } STDMETHODIMP cPanel::RemoveView( long nViewID ) { if( nViewID == m_nActiveView ) // If this is the current view, run and hide Deactivate(); CComPtr< ILayerSite > pChildSite; HRESULT hRes = m_pSite->get_Child( nViewID, ePositionByID, &pChildSite ); _ASSERTE( SUCCEEDED( hRes ) ); if( SUCCEEDED( hRes ) ) pChildSite->Destroy(); else return E_FAIL; return S_OK; } void cPanel::onCloseAccepted(long nID) { // We should only be getting commands from the button _ASSERTE( nID == 1 ); Deactivate(); } void cPanel::onAlphaInc(long nID) { // We should only be getting commands from the button _ASSERTE( nID == 2 ); if(m_pVP->alpha == -1 ) { m_pVP->alpha = m_Alpha + 5; m_pSite->put_Alpha( m_pVP->alpha ); } else { m_pVP->alpha += 5; if( m_pVP->alpha > 255 ) m_pVP->alpha = 255; m_pSite->put_Alpha( m_pVP->alpha ); } } void cPanel::onAlphaDec(long nID) { // We should only be getting commands from the button _ASSERTE( nID == 3 ); if(m_pVP->alpha == -1 ) { m_pVP->alpha = m_Alpha - 5; m_pSite->put_Alpha( m_pVP->alpha ); } else { m_pVP->alpha -= 5; if( m_pVP->alpha < 0 ) m_pVP->alpha = 0; m_pSite->put_Alpha( m_pVP->alpha ); } } STDMETHODIMP cPanel::get_ActiveView(long *pVal) { _ASSERTE( pVal != NULL ); *pVal = m_nActiveView; return S_OK; } STDMETHODIMP cPanel::LoadView(long nViewID, IView *pView, IUnknown *pSchema) { _ASSERTE( pView != NULL ); _ASSERTE( pSchema != NULL ); long nAssigned; // Set up the layer - note that it is not visible return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned ); } STDMETHODIMP cPanel::LoadViewEx(long nViewID, IView *pView, IUnknown *pSchema, long lViewFlags) { _ASSERTE( pView != NULL ); _ASSERTE( pSchema != NULL ); long nAssigned; if( lViewFlags & eTransparent ) m_bTransparent = true; // Set up the layer - note that it is not visible return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned ); } STDMETHODIMP cPanel::Deactivate() { if( m_nActiveView == -1 ) // No active view currently return S_OK; // Hide the current view by resizing to 0,0 hideView(); // Hide the entire panel static RECT rcHide = { 0, 0, 0, 0 }; m_pSite->put_Position( &rcHide ); m_nActiveView = -1; return S_OK; } STDMETHODIMP cPanel::putref_Sink(IPanelSink *newVal) { m_pSink = newVal; return S_OK; } STDMETHODIMP cPanel::MouseEvent(long nMsg, long wParam, long lParam) { static RECT rcTemp; static SIZE size; switch(nMsg) { case WM_LBUTTONDOWN: { // Pop us to the front m_pSite->moveToFront(); SIZE szBorder; m_pBorder->get_Size( &szBorder ); POINTS ptm; ptm = MAKEPOINTS(lParam); if( !cManager::_p->m_bContainer ) ptm.y-=28; if((ptm.x>=m_pVP->left+szBorder.cy) && (ptm.x<=m_pVP->left+m_pVP->width-szBorder.cy) && (ptm.y>=m_pVP->top+szBorder.cy) && (ptm.y<=m_pVP->top+28)) { m_DeltaX = ptm.x-m_pVP->left; m_DeltaY = ptm.y-m_pVP->top; m_bDragging = true; } else { if(m_pcView->Fire_Size()==VARIANT_TRUE) { if((ptm.x>=m_pVP->left) && (ptm.x<=m_pVP->left+m_pVP->width)) { if((ptm.y>=m_pVP->top) && (ptm.y<=m_pVP->top+szBorder.cy)) { m_bSizingYT = true; m_DeltaY = ptm.y-m_pVP->top; } else if((ptm.y>=m_pVP->top+m_pVP->height-szBorder.cy) && (ptm.y<=m_pVP->top+m_pVP->height)) { m_bSizingYB = true; m_DeltaY = m_pVP->top+m_pVP->height-ptm.y; } } if((ptm.y>=m_pVP->top) && (ptm.y<=m_pVP->top+m_pVP->height)) { if((ptm.x>=m_pVP->left) && (ptm.x<=m_pVP->left+szBorder.cy)) { m_bSizingXL = true; m_DeltaX = ptm.x-m_pVP->left; } else if((ptm.x>=m_pVP->left+m_pVP->width-szBorder.cy) && (ptm.x<=m_pVP->left+m_pVP->width)) { m_bSizingXR = true; m_DeltaX = m_pVP->left+m_pVP->width-ptm.x; } } } } break; } case WM_LBUTTONUP: { m_bDragging = m_bSizingXL = m_bSizingXR = m_bSizingYT = m_bSizingYB = false; break; } case WM_MOUSEMOVE: { if(wParam==MK_LBUTTON) { bool bUpdate = false; POINTS ptm; ptm = MAKEPOINTS(lParam); if( !cManager::_p->m_bContainer ) ptm.y-=28; if(m_bDragging) { m_pVP->left = ptm.x-m_DeltaX; m_pVP->top = ptm.y-m_DeltaY; /* Drakier: make sure they aren't being bad little kittens and moving the view offscreen! */ // Drakier: Get the pSite and Screen Size CComPtr< IPluginSite > pPlugin; CComPtr< IACHooks > pHooks; m_pSite->get_PluginSite( &pPlugin ); SIZE szScreen, sz; pPlugin->GetScreenSize( &sz ); szScreen.cx = sz.cx; szScreen.cy = sz.cy; long lX = sz.cx, lY = sz.cy; // Drakier: if we are not in the container, get the 3D Area if ( !cManager::_p->m_bContainer ) { pPlugin->get_Hooks( &pHooks ); pHooks->get_Area3DHeight( &lY ); pHooks->get_Area3DWidth( &lX ); pHooks.Release(); } pPlugin.Release(); // Drakier: if we are in the container, or the 3D area's are NULL if ( (cManager::_p->m_bContainer) || (&lX == NULL) || (&lY == NULL) ) { szScreen.cx = sz.cx - 308; // 308 = PANEL_SIZE szScreen.cy = sz.cy; } else // Drakier: If everything comes out right and we are not in container { if( (&lX != NULL) && (lX > 0) && (lX < 5000) ) szScreen.cx = lX; if( (&lY != NULL) && (lY > 0) && (lY < 5000) ) szScreen.cy = lY; } if ( m_pVP->left < 0 ) m_pVP->left = 0; if ( m_pVP->top < 0 ) m_pVP->top = 0; if ( (m_pVP->left + m_pVP->width) > szScreen.cx ) m_pVP->left = szScreen.cx - m_pVP->width; if ( (m_pVP->top + m_pVP->height) > szScreen.cy ) m_pVP->top = szScreen.cy - m_pVP->height; bUpdate = true; } else { if(m_bSizingYT) { rcTemp.bottom = m_pVP->height + m_pVP->top - (ptm.y-m_DeltaY); rcTemp.top = ptm.y-m_DeltaY; if(rcTemp.bottom > 34) { m_pVP->height = rcTemp.bottom; m_pVP->top = rcTemp.top; } else { m_pVP->top = (m_pVP->top + m_pVP->height) - 34; m_pVP->height = 34; } bUpdate = true; } else if(m_bSizingYB) { rcTemp.bottom = ptm.y-m_pVP->top+m_DeltaY; if(rcTemp.bottom > 34) m_pVP->height = rcTemp.bottom; else m_pVP->height = 34; bUpdate = true; } if(m_bSizingXL) { rcTemp.right = m_pVP->width + m_pVP->left - (ptm.x-m_DeltaX); rcTemp.left = ptm.x-m_DeltaX; m_pTitle->MeasureText(m_pVP->label, &size); if(rcTemp.right > size.cx + 48) { m_pVP->width = rcTemp.right; m_pVP->left = rcTemp.left; } else { m_pVP->left = (m_pVP->left + m_pVP->width) - (size.cx + 48); m_pVP->width = size.cx+48; } bUpdate = true; } else if(m_bSizingXR) { rcTemp.right = ptm.x-m_pVP->left+m_DeltaX; m_pTitle->MeasureText(m_pVP->label, &size); if(rcTemp.right > size.cx + 48) m_pVP->width = rcTemp.right; else m_pVP->width = size.cx + 48; bUpdate = true; } } if(bUpdate) { if(!m_bDragging) { //RECT rc = { m_pcView->m_VP.left, m_pcView->m_VP.top, m_pcView->m_VP.width, m_pcView->m_VP.height }; m_pcView->Fire_Sizing(/*m_pcView*//*&m_pcView->m_VP*//*m_pcView->m_VP.left, m_pcView->m_VP.top,*/ 0, 0, m_pcView->m_VP.width, m_pcView->m_VP.height-34); } static RECT rcBig = { 0, 0, 1, 1 }; m_pSite->put_Position( &rcBig ); } } break; } } return S_OK; } STDMETHODIMP cPanel::get_Transparent(VARIANT_BOOL *pVal) { *pVal = ( m_bTransparent ? VARIANT_TRUE : VARIANT_FALSE ); return S_OK; } STDMETHODIMP cPanel::put_Transparent(VARIANT_BOOL newVal) { if( newVal == VARIANT_FALSE ) m_bTransparent = false; else m_bTransparent = true; if( m_pVP->alpha == -1 ) m_pSite->put_Alpha( m_Alpha ); else m_pSite->put_Alpha( m_pVP->alpha ); m_pSite->Invalidate(); m_pSite->Reformat(); return S_OK; } STDMETHODIMP cPanel::put_Params(ViewParams *newVal) { if( newVal == NULL ) return E_POINTER; m_pVP = newVal; return S_OK; }