1453 lines
46 KiB
C++
1453 lines
46 KiB
C++
/*=============================================================================
|
|
*
|
|
* Filename: FRMSplit.cpp
|
|
* Version: 1.0
|
|
* Date: 06/11/96
|
|
* Author: V.L.
|
|
*
|
|
* Description: implementation of following classes
|
|
* CPaneFrame each pane contain a CPaneView which contain a CPaneFrame
|
|
* CPaneView each pane contain a CPaneView
|
|
* CVectorSplitterWnd the Wnd that manage splitters, call by this name
|
|
* because it could only be a (1,n) or a (n,1) splitter
|
|
* CSplitFrame a classe derived from FRMBase that contain splitter
|
|
*
|
|
*===========================================================================*/
|
|
#include "stdafx.h"
|
|
|
|
#ifdef ACTIVE_EDITOR
|
|
|
|
#include "itf/FRMSplit.hpp"
|
|
#include "itf/CPARes.h"
|
|
#include "IncTUT.h"
|
|
|
|
#define M_p_oGetSplitter() ((CVectorSplitterWnd *) GetParent()->GetParent())
|
|
|
|
#define BITMAP_HMAX IDB_HMAX
|
|
#define BITMAP_HMINLEFT IDB_HMINLEFT
|
|
#define BITMAP_HMINRIGHT IDB_HMINRIGHT
|
|
#define BITMAP_HUNDEF IDB_HUNDEF
|
|
#define BITMAP_VMAX IDB_VMAX
|
|
#define BITMAP_VMINBOTTOM IDB_VMINBOTTOM
|
|
#define BITMAP_VMINTOP IDB_VMINTOP
|
|
#define BITMAP_VUNDEF IDB_VUNDEF
|
|
|
|
/*=============================================================================
|
|
*
|
|
* CPaneFrame class
|
|
*
|
|
=============================================================================*/
|
|
IMPLEMENT_DYNCREATE(CPaneFrame, CFrameWnd)
|
|
BEGIN_MESSAGE_MAP(CPaneFrame, CFrameWnd)
|
|
ON_WM_CREATE()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_NCCALCSIZE()
|
|
ON_WM_NCHITTEST()
|
|
ON_WM_NCLBUTTONDOWN()
|
|
ON_WM_NCLBUTTONUP()
|
|
ON_WM_NCLBUTTONDBLCLK()
|
|
ON_WM_NCRBUTTONDOWN()
|
|
ON_WM_DRAWITEM()
|
|
ON_WM_MEASUREITEM()
|
|
ON_COMMAND( IDM_TILE, m_fn_vOnTile )
|
|
ON_COMMAND( IDM_MAXIMIZE, m_fn_vOnMaximize)
|
|
ON_COMMAND( IDM_REDUCE, m_fn_vOnReduce)
|
|
ON_COMMAND( IDM_MINIMIZE_TOPORLEFT, m_fn_vMinimizeUp)
|
|
ON_COMMAND( IDM_MINIMIZE_BOTTOMORRIGHT, m_fn_vMinimizeDown)
|
|
ON_COMMAND_RANGE( IDM_SAVEPOS_1, IDM_SAVEPOS_4, m_fn_vSavePos )
|
|
ON_COMMAND_RANGE( IDM_RESTOREPOS_1, IDM_RESTOREPOS_4, m_fn_vRestorePos )
|
|
END_MESSAGE_MAP()
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Constructor / destructor
|
|
*---------------------------------------------------------------------------*/
|
|
CPaneFrame::CPaneFrame() :CFrameWnd()
|
|
{
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Creation
|
|
*---------------------------------------------------------------------------*/
|
|
int CPaneFrame::OnCreate( LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* return button where point is (index of button or -1 if in caption)
|
|
* assumes that point is in the caption bar
|
|
*---------------------------------------------------------------------------*/
|
|
int CPaneFrame::m_fn_iGetButtonFromPoint( CPoint point)
|
|
{
|
|
char cButton = 0;
|
|
int iCurrentPos;
|
|
int iPos;
|
|
int iSign;
|
|
int iDeltaPos;
|
|
|
|
RECT myRect;
|
|
GetWindowRect(&myRect);
|
|
|
|
iDeltaPos = C_wCaptionHeight + 1;
|
|
|
|
switch (M_p_oGetSplitter()->m_fn_cGetType())
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
iCurrentPos = myRect.top + iDeltaPos; //myRect.bottom - C_wCaptionHeight - 2;
|
|
iPos = point.y;
|
|
iSign = 1;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
iCurrentPos = myRect.right - iDeltaPos;
|
|
iPos = point.x;
|
|
iSign = -1;
|
|
break;
|
|
}
|
|
|
|
while (m_a_iButton[cButton] != -1)
|
|
{
|
|
if ( iSign * iPos < iSign * iCurrentPos)
|
|
return cButton;
|
|
cButton++;
|
|
//iCurrentPos -= C_wCaptionHeight + 1;
|
|
iCurrentPos += iSign * iDeltaPos;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* paint a button given by a bitmap id resource in a CWindowDC at the given (x,y)
|
|
* position
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vDrawButton( CWindowDC *pDC, int iX, int iY, UINT nIDResource)
|
|
{
|
|
CBitmap bitmap;
|
|
|
|
HINSTANCE hOldInst = AfxGetResourceHandle();
|
|
HINSTANCE hNewInst = AfxGetInstanceHandle();
|
|
AfxSetResourceHandle( hNewInst );
|
|
bitmap.LoadBitmap( nIDResource );
|
|
AfxSetResourceHandle( hOldInst );
|
|
// draw bitmap
|
|
pDC->DrawState(CPoint(iX, iY), CSize(10,10), &bitmap, DST_BITMAP);
|
|
// draw button border
|
|
pDC->Draw3dRect( iX, iY, C_wCaptionHeight + 1, C_wCaptionHeight + 1, RGB(255,255,255), RGB(0,0,0) );
|
|
bitmap.DeleteObject();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* paint a horizontal caption : title and buttons
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vDrawHorizontalCaption( void )
|
|
{
|
|
CWindowDC dc(this);
|
|
RECT wRect, myRect, nRect;
|
|
CSize sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
|
|
char szName[50];
|
|
CFont xFnt, *xFntPrev;
|
|
|
|
GetWindowRect( &wRect );
|
|
GetClientRect(&myRect);
|
|
|
|
// draw caption rectangle
|
|
nRect.left = 0;
|
|
nRect.right = myRect.right;
|
|
nRect.top = 0;
|
|
nRect.bottom = C_wCaptionHeight;
|
|
dc.FillSolidRect( &nRect, ::GetSysColor(COLOR_INACTIVECAPTION) );
|
|
|
|
// draw pane text
|
|
// font specification
|
|
PLOGFONT plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));
|
|
lstrcpy(plf->lfFaceName, "Arial Narrow");
|
|
plf->lfWeight = FW_NORMAL;
|
|
plf->lfHeight = 16;
|
|
xFnt.CreateFontIndirect(plf);
|
|
xFntPrev = dc.SelectObject( &xFnt );
|
|
// draw text
|
|
GetWindowText( szName, 49);
|
|
dc.SetBkMode( TRANSPARENT);
|
|
dc.SetTextColor( ::GetSysColor(COLOR_INACTIVECAPTIONTEXT ));
|
|
dc.TextOut(5 , -2, szName);
|
|
// restore old font and destroy created one
|
|
dc.SelectObject( xFntPrev);
|
|
xFnt.DeleteObject();
|
|
|
|
// Reset the background mode to its default.
|
|
dc.SetBkMode( OPAQUE);
|
|
// Free the memory allocated for the LOGFONT structure.
|
|
LocalFree((LOCALHANDLE) plf);
|
|
|
|
// draw buttons
|
|
nRect.left = myRect.right - C_wCaptionHeight - 1;
|
|
for (int iButton = 0; m_a_iButton[iButton] != -1; iButton ++)
|
|
{
|
|
m_fn_vDrawButton( &dc, nRect.left, nRect.top, m_a_iButton[iButton]);
|
|
nRect.left -= C_wCaptionHeight + 1;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* paint a Vertical caption : title and buttons
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vDrawVerticalCaption( void )
|
|
{
|
|
CWindowDC dc(this);
|
|
RECT wRect, myRect, nRect;
|
|
CSize sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
|
|
char szName[50];
|
|
CFont xFnt, *xFntPrev;
|
|
|
|
GetWindowRect( &wRect );
|
|
GetClientRect(&myRect);
|
|
myRect.right += sizeFrame.cx;
|
|
|
|
// draw caption rectangle
|
|
nRect.left = 0;
|
|
nRect.right = C_wCaptionHeight;
|
|
nRect.top = 0;
|
|
nRect.bottom = myRect.bottom;
|
|
dc.FillSolidRect( &nRect, ::GetSysColor(COLOR_INACTIVECAPTION) );
|
|
|
|
// draw pane text : rotated text
|
|
// Allocate memory for a LOGFONT structure.
|
|
PLOGFONT plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));
|
|
lstrcpy(plf->lfFaceName, "Arial Narrow");
|
|
plf->lfWeight = FW_NORMAL;
|
|
plf->lfHeight = 12;
|
|
plf->lfEscapement = 900;
|
|
xFnt.CreateFontIndirect(plf);
|
|
xFntPrev = dc.SelectObject( &xFnt );
|
|
|
|
GetWindowText( szName, 49);
|
|
dc.SetBkMode( TRANSPARENT);
|
|
dc.SetTextColor( ::GetSysColor(COLOR_INACTIVECAPTIONTEXT ));
|
|
dc.SetTextAlign( TA_LEFT );
|
|
dc.TextOut( -2, nRect.bottom - 5, szName);
|
|
|
|
dc.SelectObject( xFntPrev);
|
|
xFnt.DeleteObject();
|
|
|
|
// Reset the background mode to its default.
|
|
dc.SetBkMode( OPAQUE);
|
|
// Free the memory allocated for the LOGFONT structure.
|
|
LocalFree((LOCALHANDLE) plf);
|
|
|
|
// draw buttons
|
|
for (int iButton = 0; m_a_iButton[iButton] != -1; iButton ++)
|
|
{
|
|
m_fn_vDrawButton( &dc, nRect.left, nRect.top, m_a_iButton[iButton]);
|
|
nRect.top += C_wCaptionHeight + 1;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCPAINT message : paint title of frame
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcPaint( void )
|
|
{
|
|
// recuperate state buttons for this window
|
|
M_p_oGetSplitter()->m_fn_vGetButton(this, m_a_iButton);
|
|
// draw title
|
|
switch (M_p_oGetSplitter()->m_fn_cGetType())
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
m_fn_vDrawVerticalCaption();
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
m_fn_vDrawHorizontalCaption();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCCALCSIZE
|
|
* return rect for view in the frame
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
|
|
{
|
|
switch (M_p_oGetSplitter()->m_fn_cGetType())
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
lpncsp->rgrc[0].left += C_wCaptionHeight;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
lpncsp->rgrc[0].top += C_wCaptionHeight;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCHITTEST
|
|
* a HTSYSMENU is returned if point is in the title bar of pane
|
|
*---------------------------------------------------------------------------*/
|
|
UINT CPaneFrame::OnNcHitTest(CPoint point)
|
|
{
|
|
RECT myRect;
|
|
|
|
GetWindowRect(&myRect);
|
|
|
|
switch (M_p_oGetSplitter()->m_fn_cGetType())
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
if (point.x < (myRect.left + C_wCaptionHeight))
|
|
return HTSYSMENU;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
if(point.y < (myRect.top + C_wCaptionHeight))
|
|
return HTSYSMENU;
|
|
break;
|
|
}
|
|
|
|
return CWnd::OnNcHitTest(point);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCLBUTTONUP
|
|
* if lbuttonup is in a button, call correspondant function
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcLButtonUp(UINT HitTest, CPoint point)
|
|
{
|
|
if (HitTest == HTSYSMENU) // we are in a pane caption
|
|
{
|
|
char cNumberOfButton = 0;
|
|
char cButton;
|
|
RECT myRect;
|
|
GetWindowRect(&myRect);
|
|
|
|
// get number of button
|
|
cButton = m_fn_iGetButtonFromPoint( point );
|
|
if (cButton != -1)
|
|
switch (m_a_iButton[cButton])
|
|
{
|
|
case BITMAP_VMAX:
|
|
case BITMAP_HMAX:
|
|
M_p_oGetSplitter()->m_fn_vMaximizePane( this );
|
|
break;
|
|
case BITMAP_VMINTOP:
|
|
case BITMAP_HMINLEFT:
|
|
M_p_oGetSplitter()->m_fn_vMinimizePane( this, FALSE );
|
|
break;
|
|
case BITMAP_VMINBOTTOM:
|
|
case BITMAP_HMINRIGHT:
|
|
M_p_oGetSplitter()->m_fn_vMinimizePane( this, TRUE );
|
|
break;
|
|
case BITMAP_VUNDEF:
|
|
case BITMAP_HUNDEF:
|
|
M_p_oGetSplitter()->m_fn_vResizePane( this );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
CWnd::OnNcLButtonUp(HitTest, point);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCLBUTTONDOWN
|
|
* if we are in the pane caption, drag the splitter bar
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcLButtonDown(UINT HitTest, CPoint point)
|
|
{
|
|
if (HitTest == HTSYSMENU) // we are in a pane caption
|
|
{
|
|
//char cNumberOfButton = 0;
|
|
RECT myRect, parentRect;
|
|
GetWindowRect(&myRect);
|
|
M_p_oGetSplitter()->GetWindowRect( &parentRect );
|
|
|
|
// get number of button
|
|
if (m_fn_iGetButtonFromPoint( point ) == -1)
|
|
{
|
|
switch (M_p_oGetSplitter()->m_fn_cGetType())
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
::SendMessage( M_p_oGetSplitter()->GetSafeHwnd(), WM_LBUTTONDOWN, 0, MAKELPARAM(myRect.left - 2 - parentRect.left, point.y - parentRect.top) );
|
|
M_p_oGetSplitter()->m_iCaptionDelta = point.x - myRect.left + 4;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
::SendMessage( M_p_oGetSplitter()->GetSafeHwnd(), WM_LBUTTONDOWN, 0, MAKELPARAM( point.x - parentRect.left, myRect.top - 2 - parentRect.top) );
|
|
M_p_oGetSplitter()->m_iCaptionDelta = point.y - myRect.top + 4;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
CWnd::OnNcLButtonDown(HitTest, point);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCLBUTTONDBLCLK : maximize the pane if in caption
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcLButtonDblClk( UINT nHitTest, CPoint point )
|
|
{
|
|
if (nHitTest == HTSYSMENU) // we are in a pane caption
|
|
if (m_fn_iGetButtonFromPoint( point ) == -1 ) // are we in the captio, not in a button
|
|
M_p_oGetSplitter()->m_fn_vMaximizePane( this ); //yes : maximize panel
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_NCRBUTTONDDOWN
|
|
* shaw a menu to perform action like button
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnNcRButtonDown( UINT nHitTest, CPoint point )
|
|
{
|
|
if (nHitTest == HTSYSMENU)
|
|
{
|
|
// create popup menu
|
|
CMenu oMenu;
|
|
CMenu oSaveMenu;
|
|
CMenu oRestoreMenu;
|
|
char cIndex;
|
|
|
|
oMenu.CreatePopupMenu();
|
|
// entries to tile all pane
|
|
oMenu.AppendMenu( MF_STRING, IDM_TILE, "Tile");
|
|
oMenu.AppendMenu( MF_SEPARATOR );
|
|
// entries that correspond to button
|
|
for (char cButton = 0; m_a_iButton[cButton] != -1; cButton ++)
|
|
{
|
|
switch (m_a_iButton[cButton])
|
|
{
|
|
case BITMAP_VMAX:
|
|
case BITMAP_HMAX:
|
|
oMenu.AppendMenu( MF_STRING, IDM_MAXIMIZE, "Big Maximize");
|
|
break;
|
|
case BITMAP_VMINTOP:
|
|
//oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_TOPORLEFT, "Minimize top");
|
|
oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_TOPORLEFT, "Maximize");
|
|
break;
|
|
case BITMAP_HMINLEFT:
|
|
//oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_TOPORLEFT, "Minimize left");
|
|
oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_TOPORLEFT, "Maximize");
|
|
break;
|
|
case BITMAP_VMINBOTTOM:
|
|
oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_BOTTOMORRIGHT, "Minimize bottom");
|
|
break;
|
|
case BITMAP_HMINRIGHT:
|
|
oMenu.AppendMenu( MF_STRING, IDM_MINIMIZE_BOTTOMORRIGHT, "Minimize right");
|
|
break;
|
|
case BITMAP_VUNDEF:
|
|
case BITMAP_HUNDEF:
|
|
oMenu.AppendMenu( MF_STRING, IDM_REDUCE, "Reduce");
|
|
break;
|
|
}
|
|
}
|
|
oMenu.AppendMenu( MF_SEPARATOR );
|
|
// creating save menu
|
|
oSaveMenu.CreatePopupMenu();
|
|
for (cIndex = 0; cIndex < 4; cIndex ++)
|
|
oSaveMenu.AppendMenu( MF_OWNERDRAW, IDM_SAVEPOS_1 + cIndex, (LPCSTR) cIndex );
|
|
oMenu.AppendMenu( MF_POPUP, (UINT) oSaveMenu.m_hMenu, "Save position" );
|
|
// creating restore menu if needed
|
|
oRestoreMenu.CreatePopupMenu();
|
|
for (cIndex = 0; cIndex < 4; cIndex ++)
|
|
{
|
|
//BOOL bGrayed = !M_p_oGetSplitter()->m_fn_bIsSavedUsed(cRestore);
|
|
//oRestoreMenu.AppendMenu( MF_OWNERDRAW | (bGrayed?MF_DISABLED:0), gs_a_uiRestoreMenuID[cRestore], "a -" );
|
|
oRestoreMenu.AppendMenu( MF_OWNERDRAW, IDM_RESTOREPOS_1 + cIndex, (LPCSTR) cIndex );
|
|
}
|
|
oMenu.AppendMenu( MF_POPUP, (UINT) oRestoreMenu.m_hMenu, "Restore position" );
|
|
|
|
// register the popup menu for the tutorial module
|
|
TUT_M_vGetTutDll ();
|
|
TUT_M_vRegisterMenu (this -> m_hWnd , oMenu . m_hMenu , point . x , point . y);
|
|
|
|
// display & track popup menu
|
|
oMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
|
|
// destroy menu
|
|
oSaveMenu.DestroyMenu();
|
|
oRestoreMenu.DestroyMenu();
|
|
oMenu.DestroyMenu();
|
|
M_p_oGetSplitter()->m_iPopupClosed = 1;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_MEASUREITEM message
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMIS )
|
|
{
|
|
if (lpMIS->CtlType == ODT_MENU)
|
|
{
|
|
lpMIS->itemWidth = 110;
|
|
lpMIS->itemHeight = 20;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_MEASUREITEM message
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDIS )
|
|
{
|
|
char cIndex;
|
|
|
|
if (lpDIS->CtlType == ODT_MENU)
|
|
{
|
|
CDC *pDC = CDC::FromHandle (lpDIS->hDC);
|
|
cIndex = (char) lpDIS->itemData;
|
|
/*
|
|
if ( (lpDIS->itemID >= IDM_SAVEPOS_1) && (lpDIS->itemID <= IDM_SAVEPOS_4) )
|
|
cIndex = lpDIS->itemID - IDM_SAVEPOS_1;
|
|
else
|
|
cIndex = lpDIS->itemID - IDM_RESTOREPOS_1;
|
|
*/
|
|
pDC->FillSolidRect( &lpDIS->rcItem, GetSysColor( COLOR_MENU ) );
|
|
if (M_p_oGetSplitter()->m_fn_bIsSavedUsed(cIndex))
|
|
{
|
|
float fRatio[16];
|
|
RECT myRect;
|
|
float fTotal;
|
|
char cPane;
|
|
CPen oGrayPen( PS_SOLID, 1, RGB(192,192,192) );
|
|
|
|
|
|
myRect.left = lpDIS->rcItem.left + 5;
|
|
myRect.right = lpDIS->rcItem.right -5;
|
|
fTotal = (float) (myRect.right - myRect.left - 3 * M_p_oGetSplitter()->m_fn_iGetNumberOfPanes() - 1);
|
|
myRect.top = lpDIS->rcItem.top + 2;
|
|
myRect.bottom = lpDIS->rcItem.bottom - 2;
|
|
|
|
M_p_oGetSplitter()->m_fn_vGetPositionRatio( cIndex, fRatio );
|
|
|
|
for (cPane = 0; cPane < M_p_oGetSplitter()->m_fn_iGetNumberOfPanes(); cPane ++ )
|
|
{
|
|
myRect.right = myRect.left + 4 + (long) ((fRatio[cPane] * fTotal) + 0.5);
|
|
pDC->SelectObject( GetStockObject( BLACK_PEN ) );
|
|
pDC->Rectangle ( &myRect );
|
|
pDC->SelectObject( oGrayPen );
|
|
pDC->MoveTo( myRect.left + 1, myRect.top + 1 );
|
|
pDC->LineTo( myRect.left + 1, myRect.bottom - 1);
|
|
pDC->MoveTo( myRect.left + 2, myRect.top + 1 );
|
|
pDC->LineTo( myRect.left + 2, myRect.bottom - 1);
|
|
myRect.left = myRect.right - 1;
|
|
}
|
|
}
|
|
else
|
|
pDC->DrawText( "Empty", 5, &lpDIS->rcItem, DT_SINGLELINE|DT_CENTER|DT_VCENTER );
|
|
|
|
if (lpDIS->itemState & ODS_SELECTED)
|
|
pDC->InvertRect( &lpDIS->rcItem );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND( IDM_TILE)
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vOnTile( void )
|
|
{
|
|
M_p_oGetSplitter()->m_fn_vTilePanes( );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND( IDM_MAXIMIZE)
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vOnMaximize( void )
|
|
{
|
|
M_p_oGetSplitter()->m_fn_vMaximizePane( this );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND( IDM_REDUCE)
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vOnReduce( void )
|
|
{
|
|
M_p_oGetSplitter()->m_fn_vResizePane( this );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND( IDM_MINIMIZE_TOPORLEFT)
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vMinimizeUp( void )
|
|
{
|
|
M_p_oGetSplitter()->m_fn_vMinimizePane( this, FALSE );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND( IDM_MINIMIZE_BOTTOMORRIGHT )
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vMinimizeDown( void )
|
|
{
|
|
M_p_oGetSplitter()->m_fn_vMinimizePane( this, TRUE );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND_RANGE( IDM_SAVEPOS_1 to IDM_SAVEPOS_4 )
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vSavePos( UINT uID )
|
|
{
|
|
char cSave = uID - IDM_SAVEPOS_1;
|
|
M_p_oGetSplitter()->m_fn_vSavePos( cSave );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* handle function for WM_COMMAND_RANGE( IDM_RESTOREPOS_1 to IDM_RESTOREPOS_4 )
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneFrame::m_fn_vRestorePos( UINT uID )
|
|
{
|
|
char cRestore = uID - IDM_RESTOREPOS_1;
|
|
M_p_oGetSplitter()->m_fn_vRestorePos( cRestore );
|
|
}
|
|
|
|
|
|
|
|
/*=============================================================================
|
|
*
|
|
* CPaneView class
|
|
*
|
|
=============================================================================*/
|
|
IMPLEMENT_DYNCREATE(CPaneView, CView)
|
|
BEGIN_MESSAGE_MAP(CPaneView, CView)
|
|
ON_WM_CREATE()
|
|
ON_WM_SIZE()
|
|
END_MESSAGE_MAP()
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* constructor
|
|
*---------------------------------------------------------------------------*/
|
|
CPaneView::CPaneView() : CView()
|
|
{
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* creation
|
|
*---------------------------------------------------------------------------*/
|
|
int CPaneView::OnCreate( LPCREATESTRUCT lpCreateStruct )
|
|
{
|
|
if (CView::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
RECT rect;
|
|
rect.left = 0;
|
|
rect.top = 0;
|
|
rect.bottom = lpCreateStruct->cy;
|
|
rect.right = lpCreateStruct->cx;
|
|
|
|
m_p_oPaneFrame = new CPaneFrame();
|
|
m_p_oPaneFrame->Create(NULL, "truc", WS_OVERLAPPED | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD, rect, this);
|
|
m_p_oPaneFrame->ShowWindow(TRUE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* draw view : nothing to do, entire view is recovered
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneView::OnDraw( CDC* pDC )
|
|
{
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* view is resize, resize frame that is in
|
|
*---------------------------------------------------------------------------*/
|
|
void CPaneView::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
CView::OnSize( nType, cx, cy);
|
|
m_p_oPaneFrame->MoveWindow(0,0,cx,cy);
|
|
}
|
|
|
|
|
|
/*=============================================================================
|
|
*
|
|
* CVectorSplitterWnd class
|
|
*
|
|
=============================================================================*/
|
|
//define for each case width
|
|
#define C_cMinimized 0
|
|
#define C_cMaximized 1
|
|
#define C_cShortMaximized 2
|
|
#define C_cUndefined 3
|
|
|
|
IMPLEMENT_DYNCREATE(CVectorSplitterWnd, CSplitterWnd)
|
|
BEGIN_MESSAGE_MAP(CVectorSplitterWnd, CSplitterWnd)
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_SIZE()
|
|
ON_WM_MOUSEWHEEL()
|
|
END_MESSAGE_MAP()
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* Constructor / destructor
|
|
*---------------------------------------------------------------------------*/
|
|
CVectorSplitterWnd::CVectorSplitterWnd() : CSplitterWnd()
|
|
{
|
|
m_cxSplitterGap = m_cySplitterGap = 4;
|
|
m_cxBorder = m_cyBorder = 2;
|
|
m_cxSplitter = m_cySplitter = 4;
|
|
|
|
m_aa_iSavePosition[0][0] = -1;
|
|
m_aa_iSavePosition[1][0] = -1;
|
|
m_aa_iSavePosition[2][0] = -1;
|
|
m_aa_iSavePosition[3][0] = -1;
|
|
}
|
|
|
|
CVectorSplitterWnd::~CVectorSplitterWnd()
|
|
{
|
|
}
|
|
|
|
BOOL CVectorSplitterWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* splitter window is resized
|
|
* compute max size and tile size
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
CSplitterWnd::OnSize(nType, cx, cy);
|
|
CRect myRect;
|
|
GetInsideRect (myRect);
|
|
if (m_cType == C_cHorizontalSplitter)
|
|
{
|
|
m_iMaximizedSize = ( myRect.right - myRect.left) - (m_iNumberOfPanes - 1 ) * (C_wCaptionHeight + m_cxSplitterGap);
|
|
m_iTileSize = ((myRect.right - myRect.left) - (m_iNumberOfPanes - 1) * m_cxSplitterGap ) / m_iNumberOfPanes;
|
|
}
|
|
else
|
|
{
|
|
m_iMaximizedSize = ( myRect.bottom- myRect.top) - (m_iNumberOfPanes - 1 ) * (C_wCaptionHeight + m_cxSplitterGap);
|
|
m_iTileSize = ((myRect.bottom - myRect.top) - (m_iNumberOfPanes - 1) * m_cySplitterGap ) / m_iNumberOfPanes;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* get row and col number of a given pane
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vPaneToRowCol( int _iPane, int& _iRow,int &_iCol)
|
|
{
|
|
switch (m_cType)
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
_iRow = 0;
|
|
_iCol = _iPane;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
_iRow = _iPane;
|
|
_iCol = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* get pane index from given row and col
|
|
*---------------------------------------------------------------------------*/
|
|
int CVectorSplitterWnd::m_fn_iRowColToPane( int _iRow,int _iCol)
|
|
{
|
|
return ( ((_iRow + 1) * (_iCol + 1)) - 1);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* return size of a pane, size is the width for an horizontal splitter,
|
|
* the height for a vertical splitter
|
|
*---------------------------------------------------------------------------*/
|
|
int CVectorSplitterWnd::m_fn_iGetPaneSize( int _iPane )
|
|
{
|
|
int iSize = 0, iSizeMin;
|
|
switch (m_cType)
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
GetColumnInfo( _iPane, iSize, iSizeMin );
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
GetRowInfo( _iPane, iSize, iSizeMin );
|
|
break;
|
|
}
|
|
return iSize;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* set the size of a pane, size is the width for an horizontal splitter,
|
|
* the height for a vertical splitter
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vSetPaneSize( int _iPane, int _iSize )
|
|
{
|
|
int iSize, iSizeMin;
|
|
switch (m_cType)
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
GetColumnInfo( _iPane, iSize, iSizeMin );
|
|
SetColumnInfo( _iPane, _iSize, iSizeMin );
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
GetRowInfo( _iPane, iSize, iSizeMin );
|
|
SetRowInfo( _iPane, _iSize, iSizeMin );
|
|
break;
|
|
}
|
|
// set state for the pane that change
|
|
if ( _iSize == C_wCaptionHeight)
|
|
m_a_cState[_iPane] = C_cMinimized;
|
|
else if (_iSize == m_iMaximizedSize)
|
|
m_a_cState[_iPane] = C_cMaximized;
|
|
else
|
|
{
|
|
m_a_cState[_iPane] = C_cUndefined;
|
|
m_a_iSize[_iPane] = _iSize;
|
|
}
|
|
RecalcLayout();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* create the statc splitter window
|
|
* _ctype = C_cHorizontalSplitter : create a splitter of 1 row and _iNumberOfPanes columns
|
|
* _ctype = C_cVerticalSplitter : create a splitter of 1 column and _iNumberOfPanes rows
|
|
* create for each pane a CTestView
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CVectorSplitterWnd::Create( CWnd *_pParentWnd, char _cType, int _iNumberOfPanes )
|
|
{
|
|
int iRow;
|
|
int iCol;
|
|
int iPane;
|
|
int iSize;
|
|
CRect myRect;
|
|
SIZE sz;
|
|
|
|
m_cType = _cType;
|
|
m_iNumberOfPanes = _iNumberOfPanes;
|
|
m_fn_vPaneToRowCol( _iNumberOfPanes - 1, iRow, iCol);
|
|
iRow ++;
|
|
iCol ++;
|
|
|
|
BOOL bResult = CreateStatic( _pParentWnd, iRow, iCol );
|
|
|
|
_pParentWnd->GetWindowRect( &myRect );
|
|
|
|
switch ( _cType )
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
m_iMaximizedSize = myRect.right - myRect.left - (m_iNumberOfPanes - 1) * (m_cxSplitter + C_wCaptionHeight + m_cxBorder);
|
|
sz.cx = iSize = (m_iMaximizedSize / m_iNumberOfPanes) + C_wCaptionHeight;
|
|
sz.cy = 10;
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
m_iMaximizedSize = myRect.bottom - myRect.top - (m_iNumberOfPanes - 1) * (m_cySplitter + C_wCaptionHeight + m_cyBorder);
|
|
sz.cx = 10;
|
|
sz.cy = iSize = (m_iMaximizedSize / m_iNumberOfPanes) + C_wCaptionHeight;
|
|
break;
|
|
}
|
|
|
|
for (iPane = 0; iPane < _iNumberOfPanes; iPane++)
|
|
{
|
|
m_a_cState[iPane] = C_cUndefined;
|
|
m_a_iSize[iPane] = iSize;
|
|
m_fn_vPaneToRowCol( iPane, iRow, iCol);
|
|
bResult &= CSplitterWnd::CreateView( iRow, iCol, RUNTIME_CLASS( CPaneView ), sz, NULL);
|
|
switch( _cType )
|
|
{
|
|
case C_cHorizontalSplitter:
|
|
SetColumnInfo( iPane, iSize, C_wCaptionHeight );
|
|
break;
|
|
case C_cVerticalSplitter:
|
|
SetRowInfo( iPane, iSize, C_wCaptionHeight );
|
|
break;
|
|
}
|
|
}
|
|
RecalcLayout();
|
|
return bResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* fill the CPaneView of the given pane with a CPaneFrame and a view of given type
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CVectorSplitterWnd::CreateView( int _iPane, CRuntimeClass *_pViewClass, char *_szName, int _iSize)
|
|
{
|
|
int iRow, iCol;
|
|
CWnd *pView;
|
|
|
|
// set name in upper case
|
|
CString strUpr(_szName);
|
|
strUpr.MakeUpper();
|
|
|
|
m_fn_vPaneToRowCol( _iPane, iRow, iCol );
|
|
|
|
CPaneView *pPaneView = (CPaneView *) GetPane( iRow, iCol);
|
|
pPaneView->m_fn_p_oGetFrame()->SetWindowText( strUpr );
|
|
|
|
/* pView = new CFormView();
|
|
pView->Create(NULL, "", WS_VISIBLE|WS_CHILD, CRect(0,0,0,0), GetParent(), AFX_IDW_PANE_FIRST, NULL);
|
|
pView->UpdateData(FALSE);
|
|
SetPaneView(0, pView, _szName, _iSize);*/
|
|
|
|
CCreateContext creat;
|
|
creat.m_pNewViewClass = _pViewClass;
|
|
pView = pPaneView->m_fn_p_oGetFrame()->CreateView( &creat );
|
|
pView->ShowWindow(TRUE);
|
|
pView->ModifyStyle(WS_BORDER, 0);
|
|
pPaneView->m_fn_p_oGetFrame()->SetActiveView((CView *) pView, TRUE);
|
|
|
|
// change size of view
|
|
if (_iSize > 0)
|
|
m_fn_vSetPaneSize( _iPane, _iSize );
|
|
//m_fn_vChangePaneSize( _iPane, _iSize );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* fill the CPaneView of the given pane with a CPaneFrame and a view of given type
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CVectorSplitterWnd::SetPaneView( int _iPane, CView *_pView, char *_szName, int _iSize)
|
|
{
|
|
int iRow, iCol;
|
|
|
|
//set all char of name in upper case
|
|
CString str(_szName);
|
|
str.MakeUpper();
|
|
|
|
m_fn_vPaneToRowCol( _iPane, iRow, iCol );
|
|
|
|
CPaneView *pPaneView = (CPaneView *) GetPane( iRow, iCol);
|
|
pPaneView->m_fn_p_oGetFrame()->SetWindowText( str );
|
|
_pView->SetParent( pPaneView->m_fn_p_oGetFrame() );
|
|
pPaneView->m_fn_p_oGetFrame()->SetActiveView((CView *) _pView, TRUE);
|
|
|
|
// change size of view
|
|
if (_iSize > 0)
|
|
m_fn_vSetPaneSize( _iPane, _iSize );
|
|
//m_fn_vChangePaneSize( _iPane, _iSize );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that return the first not minimized pane in one direction
|
|
*---------------------------------------------------------------------------*/
|
|
int CVectorSplitterWnd::m_fn_iGetNextOpenPane( int iFromPane, BOOL bBottomOrRight )
|
|
{
|
|
int iPane;
|
|
int iSens = (bBottomOrRight)?+1:-1;
|
|
|
|
for (iPane = iFromPane + iSens; ; iPane += iSens)
|
|
{
|
|
if ((iPane == -1) || (iPane == m_iNumberOfPanes))
|
|
return -1;
|
|
if (m_a_cState[iPane] != C_cMinimized)
|
|
return iPane;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that return the first not minimized pane in one direction
|
|
*---------------------------------------------------------------------------*/
|
|
int CVectorSplitterWnd::m_fn_iGetNextPane( int iFromPane, BOOL bBottomOrRight )
|
|
{
|
|
int iPane = iFromPane + ((bBottomOrRight)?+1:-1);
|
|
if ((iPane == -1) || (iPane == m_iNumberOfPanes))
|
|
return -1;
|
|
return iPane;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that change size of a pane
|
|
* change size of a window, freed or taken place is given to upper or rightmost pane
|
|
* if bBottomOrRight is False.
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vChangePaneSize( int _iPane, int _iNewSize, BOOL bBottomOrRight)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
int iOldSize = m_fn_iGetPaneSize( _iPane );
|
|
int iDelta = _iNewSize - iOldSize; // <0 => pane is reduce else pane size is increased;
|
|
int iDelta2;
|
|
int iPaneDest;
|
|
BOOL bAlreadyInversed = FALSE;
|
|
int a_iSize[16];
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if ( _iNewSize >= m_iMaximizedSize )
|
|
{
|
|
m_fn_vMaximizePane( m_fn_p_oGetPane( _iPane )->GetParent() );
|
|
return;
|
|
}
|
|
|
|
if ( iOldSize == 0 )
|
|
return;
|
|
|
|
if (iDelta == 0)
|
|
return;
|
|
|
|
if (iDelta < 0) // pane is reduce, must give place to another window
|
|
{
|
|
// get first not minimized pane
|
|
iPaneDest = m_fn_iGetNextOpenPane( _iPane, bBottomOrRight );
|
|
// if none get next pane
|
|
if (iPaneDest == -1)
|
|
{
|
|
iPaneDest = m_fn_iGetNextPane( _iPane, bBottomOrRight );
|
|
// it's already the last or first pane
|
|
if (iPaneDest == -1)
|
|
{
|
|
// change direction
|
|
bBottomOrRight = !bBottomOrRight;
|
|
iPaneDest = m_fn_iGetNextOpenPane( _iPane, bBottomOrRight );
|
|
// none opened in the other direction too
|
|
if (iPaneDest == -1)
|
|
iPaneDest = m_fn_iGetNextPane( _iPane, bBottomOrRight );
|
|
}
|
|
}
|
|
iOldSize = m_fn_iGetPaneSize( iPaneDest );
|
|
m_fn_vChangePaneSize( iPaneDest, iOldSize - iDelta, (iPaneDest < _iPane));
|
|
}
|
|
else
|
|
{
|
|
for (iPaneDest = 0; iPaneDest < m_iNumberOfPanes; iPaneDest++)
|
|
a_iSize[ iPaneDest ] = m_fn_iGetPaneSize( iPaneDest );
|
|
|
|
// must recuperate some place in others pane
|
|
iPaneDest = _iPane;
|
|
while (iDelta)
|
|
{
|
|
iPaneDest += bBottomOrRight ? 1 : -1;
|
|
if ( (iPaneDest < 0) || (iPaneDest >= m_iNumberOfPanes) )
|
|
{
|
|
bBottomOrRight = !bBottomOrRight;
|
|
iPaneDest = _iPane;
|
|
}
|
|
else
|
|
{
|
|
if ( a_iSize[ iPaneDest ] > C_wCaptionHeight )
|
|
{
|
|
iDelta2 = a_iSize[ iPaneDest ] - C_wCaptionHeight;
|
|
if (iDelta2 >= iDelta)
|
|
{
|
|
a_iSize[ iPaneDest ] -= iDelta;
|
|
iDelta = 0;
|
|
}
|
|
else
|
|
{
|
|
iDelta -= iDelta2;
|
|
a_iSize[ iPaneDest ] = C_wCaptionHeight;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
a_iSize[ _iPane ] = _iNewSize;
|
|
for (iPaneDest = 0; iPaneDest < m_iNumberOfPanes; iPaneDest++)
|
|
m_fn_vSetPaneSize( iPaneDest, a_iSize[ iPaneDest ] );
|
|
}
|
|
RecalcLayout();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that handle HitTest
|
|
*---------------------------------------------------------------------------*/
|
|
int CVectorSplitterWnd::HitTest(CPoint pt) const
|
|
{
|
|
return CSplitterWnd::HitTest( pt );
|
|
/*
|
|
int iHit = CSplitterWnd::HitTest( pt );
|
|
int iPane = 0;
|
|
|
|
if ( ((iHit>= 201) && (iHit <= 215)) || ((iHit >= 101) && (iHit <= 115)) )
|
|
{
|
|
for (iPane = (iHit % 100) - 1; iPane < m_iNumberOfPanes; iPane ++)
|
|
if (m_a_cState[iPane]!=C_cMinimized)
|
|
return iHit;
|
|
return 0;
|
|
}
|
|
return iHit;
|
|
*/
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that handle OnMouseMove message
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::OnMouseMove(UINT nFlags, CPoint pt)
|
|
{
|
|
if (m_iPopupClosed)
|
|
m_iPopupClosed = 0;
|
|
else
|
|
m_iCaptionDelta = 0;
|
|
|
|
CSplitterWnd :: OnMouseMove( nFlags, pt );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that handle OnLButtonDown message
|
|
*---------------------------------------------------------------------------*/
|
|
CRect g_oRectTracker;
|
|
|
|
void CVectorSplitterWnd::OnLButtonDown(UINT nFlags, CPoint pt)
|
|
{
|
|
CRect myRect;
|
|
CSplitterWnd::OnLButtonDown( 0, pt );
|
|
|
|
int hit = HitTest( pt );
|
|
if ( (m_cType == C_cHorizontalSplitter) && (hit >= 201) && (hit <= 215) )
|
|
{
|
|
hit -= 201;
|
|
GetInsideRect( myRect );
|
|
m_rectLimit.right -= ( m_iNumberOfPanes - 1 - hit) * (C_wCaptionHeight + m_cxSplitterGap) - m_cxSplitterGap;
|
|
m_rectLimit.left = myRect.left + ( hit + 1) * ( C_wCaptionHeight + m_cxSplitterGap) - m_cxSplitterGap;
|
|
m_iTrackPane = hit;
|
|
}
|
|
else if ((m_cType == C_cVerticalSplitter) && (hit >= 101) && (hit <= 115) )
|
|
{
|
|
hit -= 101;
|
|
GetInsideRect( myRect );
|
|
m_rectLimit.bottom -= ( m_iNumberOfPanes - 1 - hit) * (C_wCaptionHeight + m_cySplitterGap) - m_cySplitterGap;
|
|
m_rectLimit.top = myRect.top + ( hit + 1) * ( C_wCaptionHeight + m_cySplitterGap ) - m_cySplitterGap;
|
|
m_iTrackPane = hit;
|
|
}
|
|
else
|
|
m_iTrackPane = -1;
|
|
m_oBeginPoint = pt;
|
|
g_oRectTracker = m_rectTracker;
|
|
g_oRectTracker.OffsetRect( -1, -1);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* function that handle OnLButtonUp message
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::OnLButtonUp(UINT nFlags, CPoint pt)
|
|
{
|
|
if (m_iTrackPane != -1)
|
|
{
|
|
int iDelta;
|
|
ASSERT_VALID(this);
|
|
|
|
if (!m_bTracking)
|
|
return;
|
|
|
|
ReleaseCapture();
|
|
|
|
// erase tracker rectangle
|
|
OnInvertTracker(m_rectTracker);
|
|
if (m_bTracking2)
|
|
OnInvertTracker(m_rectTracker2);
|
|
m_bTracking = m_bTracking2 = FALSE;
|
|
|
|
// save old active view
|
|
CWnd* pOldActiveView = GetActivePane();
|
|
|
|
// m_rectTracker is set to the new splitter position (without border) (so, adjust relative to where the border will be)
|
|
m_rectTracker.OffsetRect(-1 , -1);
|
|
m_rectTracker2.OffsetRect(-1, -1 );
|
|
|
|
if (m_cType == C_cHorizontalSplitter)
|
|
iDelta = m_rectTracker.left - g_oRectTracker.left;
|
|
else
|
|
iDelta = m_rectTracker.top - g_oRectTracker.top;
|
|
|
|
if (iDelta > 0)
|
|
{
|
|
//int iPane = m_fn_iGetNextOpenPane( m_iTrackPane + 1, FALSE);
|
|
//if (iPane == -1)
|
|
int iPane = m_iTrackPane;
|
|
m_fn_vChangePaneSize( iPane, m_fn_iGetPaneSize( iPane ) + iDelta );
|
|
}
|
|
else
|
|
{
|
|
//int iPane = m_fn_iGetNextOpenPane( m_iTrackPane, TRUE);
|
|
//if (iPane == -1)
|
|
int iPane = m_fn_iGetNextPane( m_iTrackPane, TRUE);
|
|
m_fn_vChangePaneSize( iPane, m_fn_iGetPaneSize( iPane ) - iDelta, iPane < m_iTrackPane );
|
|
}
|
|
|
|
if (pOldActiveView == GetActivePane())
|
|
{
|
|
if (pOldActiveView != NULL)
|
|
{
|
|
SetActivePane(-1, -1, pOldActiveView); // re-activate
|
|
pOldActiveView->SetFocus(); // make sure focus is restored
|
|
}
|
|
}
|
|
}
|
|
else
|
|
CSplitterWnd::OnLButtonUp(nFlags, pt);
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* return view associated with the frame and the view pane
|
|
*---------------------------------------------------------------------------*/
|
|
CWnd *CVectorSplitterWnd::m_fn_p_oGetPane( int _iPane )
|
|
{
|
|
int iRow, iCol;
|
|
m_fn_vPaneToRowCol( _iPane, iRow, iCol );
|
|
CPaneView *pPaneView = (CPaneView *) CSplitterWnd::GetPane(iRow, iCol);
|
|
CPaneFrame *pFrame = pPaneView->m_fn_p_oGetFrame();
|
|
return pFrame->GetActiveView();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* minimize the given panel. bTop is true if it's the up (or left) pane that takes
|
|
* the place free by minimized pane
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vMinimizePane( CWnd *p_xPane, BOOL _bTop /*= TRUE */)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
int iRow;
|
|
int iCol;
|
|
int iSize;
|
|
int iPane;
|
|
int iPaneDest;
|
|
int iSizeDest;
|
|
int iSaveSize = -1;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if ( IsChildPane( p_xPane->GetParent(), &iRow, &iCol ) )
|
|
{
|
|
iPane = m_fn_iRowColToPane( iRow, iCol );
|
|
|
|
if (iPane == 0) // first pane
|
|
return; //_bTop = FALSE;
|
|
|
|
if ( !_bTop)
|
|
{
|
|
// short maximize (minimize top or left window)
|
|
iSaveSize = m_a_iSize[ iPane ];
|
|
iPane--;
|
|
}
|
|
|
|
if (iPane == m_iNumberOfPanes - 1) // last pane
|
|
_bTop = TRUE;
|
|
|
|
iPaneDest = m_fn_iGetNextPane( iPane, !_bTop);
|
|
|
|
iSize = m_fn_iGetPaneSize( iPane );
|
|
iSizeDest = m_fn_iGetPaneSize( iPaneDest );
|
|
|
|
if ( iSizeDest + iSize - C_wCaptionHeight >= m_iMaximizedSize )
|
|
{
|
|
m_fn_vMaximizePane( m_fn_p_oGetPane( iPaneDest )->GetParent() );
|
|
return;
|
|
}
|
|
|
|
m_a_cCloseDir[iPane] = !(_bTop);
|
|
|
|
m_fn_vSetPaneSize( iPaneDest, iSizeDest + iSize - C_wCaptionHeight );
|
|
m_fn_vSetPaneSize( iPane, C_wCaptionHeight );
|
|
|
|
if (iSaveSize != -1)
|
|
{
|
|
// short maximize
|
|
m_a_cState[ iPane + 1 ] = C_cShortMaximized;
|
|
m_a_iSize[ iPane + 1 ] = iSaveSize;
|
|
}
|
|
RecalcLayout();
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* maximize the given panel.
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vMaximizePane( CWnd *p_xPane )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
int iRow, iCol;
|
|
int iPane, iPane2;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if (IsChildPane( p_xPane->GetParent(), &iRow, &iCol ) )
|
|
{
|
|
iPane = m_fn_iRowColToPane( iRow, iCol );
|
|
|
|
for (iPane2 = 0; (iPane2 < m_iNumberOfPanes) && (m_a_cState[iPane2] != C_cMaximized); iPane2++);
|
|
|
|
if (iPane2 == m_iNumberOfPanes)
|
|
for (iPane2 = 0; iPane2 < m_iNumberOfPanes; iPane2++)
|
|
m_a_iSizeBeforeMax[iPane2] = m_fn_iGetPaneSize( iPane2 );
|
|
|
|
for (iPane2 = 0; iPane2 < m_iNumberOfPanes; iPane2++)
|
|
{
|
|
if (iPane2 != iPane)
|
|
m_fn_vSetPaneSize( iPane2, C_wCaptionHeight );
|
|
}
|
|
m_fn_vSetPaneSize( iPane, m_iMaximizedSize);
|
|
RecalcLayout();
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* tile all pane
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vTilePanes( void )
|
|
{
|
|
int iPane;
|
|
for (iPane = 0; iPane < m_iNumberOfPanes; iPane++)
|
|
m_fn_vSetPaneSize( iPane, m_iTileSize );
|
|
RecalcLayout();
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* resize a panel to saved size
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vResizePane( CWnd *p_xPane)
|
|
{
|
|
int iRow, iCol, iPane;
|
|
if (IsChildPane( p_xPane->GetParent(), &iRow, &iCol) )
|
|
{
|
|
iPane = m_fn_iRowColToPane( iRow, iCol );
|
|
if (m_a_cState[iPane] == C_cMaximized)
|
|
{
|
|
for (iPane = 0; iPane < m_iNumberOfPanes; iPane ++)
|
|
m_fn_vSetPaneSize( iPane, m_a_iSizeBeforeMax[iPane] );
|
|
RecalcLayout();
|
|
}
|
|
else
|
|
{
|
|
if (m_a_cState[iPane] == C_cShortMaximized)
|
|
m_fn_vChangePaneSize( iPane - 1, m_a_iSize[iPane - 1], m_a_cCloseDir[iPane - 1]);
|
|
else
|
|
m_fn_vChangePaneSize( iPane, m_a_iSize[iPane], m_a_cCloseDir[iPane]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* save current pane size in the given save index
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vSavePos( char cSave )
|
|
{
|
|
for (char cPane = 0; cPane < m_iNumberOfPanes; cPane ++)
|
|
m_aa_iSavePosition[cSave][cPane] = m_fn_iGetPaneSize( cPane );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* save current pane size in the given save index
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vRestorePos( char cRestore )
|
|
{
|
|
if (m_aa_iSavePosition[cRestore][0] != -1)
|
|
{
|
|
for (char cPane = 0; cPane < m_iNumberOfPanes; cPane ++)
|
|
m_fn_vSetPaneSize( cPane, m_aa_iSavePosition[cRestore][cPane] );
|
|
RecalcLayout();
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* say if position is saved at the given index of save position array
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CVectorSplitterWnd::m_fn_bIsSavedUsed( char cSave )
|
|
{
|
|
return (m_aa_iSavePosition[cSave][0] != -1);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* return an array of ratio for space occupied by each pane
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vGetPositionRatio( char cSave, float *p_a_fRatio16 )
|
|
{
|
|
char cPane;
|
|
for (cPane = 0; cPane < m_iNumberOfPanes; cPane ++)
|
|
p_a_fRatio16[cPane] = (float) (m_aa_iSavePosition[cSave][cPane] - C_wCaptionHeight) / (m_iMaximizedSize - C_wCaptionHeight);
|
|
for (;cPane < 16; cPane ++)
|
|
p_a_fRatio16[cPane] = -1;
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* compute button list for a pane
|
|
*---------------------------------------------------------------------------*/
|
|
void CVectorSplitterWnd::m_fn_vGetButton( CWnd *p_xPane, int *p_a_iButton )
|
|
{
|
|
int iRow, iCol, iPane;
|
|
char cButton = 0;
|
|
|
|
// get row and col dor this child
|
|
if (IsChildPane( p_xPane->GetParent(), &iRow, &iCol ) )
|
|
{
|
|
//retrive panel number
|
|
iPane = m_fn_iRowColToPane( iRow, iCol );
|
|
// add maximize button if pane isn't in maximize state
|
|
if (m_a_cState[iPane] != C_cMaximized)
|
|
p_a_iButton[cButton++] = (m_cType == C_cHorizontalSplitter)?BITMAP_HMAX:BITMAP_VMAX;
|
|
// add resize button if pane is in min or max state
|
|
if (m_a_cState[iPane] != C_cUndefined)
|
|
p_a_iButton[cButton++] = (m_cType == C_cHorizontalSplitter)?BITMAP_HUNDEF:BITMAP_VUNDEF;
|
|
// add short maximize button if previous pane is not minimized
|
|
if ( (iPane != 0) && ( m_a_cState[ iPane - 1 ] != C_cMinimized ) )
|
|
p_a_iButton[cButton++] = (m_cType == C_cHorizontalSplitter)?BITMAP_HMINLEFT:BITMAP_VMINTOP;
|
|
// add minimize button if pane is not in min state
|
|
if ( (iPane != 0) && (m_a_cState[iPane] != C_cMinimized) )
|
|
p_a_iButton[cButton++] = (m_cType == C_cHorizontalSplitter)?BITMAP_HMINRIGHT:BITMAP_VMINBOTTOM;
|
|
}
|
|
// set next button to -1
|
|
p_a_iButton[cButton] = -1;
|
|
}
|
|
|
|
|
|
/*=============================================================================
|
|
*
|
|
* CSplitFrame class
|
|
*
|
|
=============================================================================*/
|
|
|
|
IMPLEMENT_DYNCREATE(CSplitFrame, FRMBase)
|
|
BEGIN_MESSAGE_MAP(CSplitFrame, FRMBase)
|
|
ON_WM_SYSCOMMAND()
|
|
END_MESSAGE_MAP()
|
|
|
|
void CSplitFrame::OnSysCommand(UINT nID, LPARAM lParam)
|
|
{
|
|
if(nID==SC_CLOSE)
|
|
M_GetMainWnd()->SendMessage(WM_CLOSE);
|
|
else
|
|
FRMBase::OnSysCommand(nID,lParam);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* constructor
|
|
*---------------------------------------------------------------------------*/
|
|
CSplitFrame::CSplitFrame() : FRMBase()
|
|
{
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* create splitter
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CSplitFrame::CreateSplitter( char cType, int iNumberOfPanes )
|
|
{
|
|
m_p_oView = new CVectorSplitterWnd();
|
|
return m_p_oView->Create(this, cType, iNumberOfPanes);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* create and associate a view to the CPaneFrame that is associated with the
|
|
* CPaneView off the given pane
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CSplitFrame::CreateView( int iPane, CRuntimeClass *pViewClass, char *szName, int iSize)
|
|
{
|
|
BOOL bResult = m_p_oView->CreateView(iPane, pViewClass, szName, iSize );
|
|
return bResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* associate a view to the CPaneFrame that is associated with the CPaneView
|
|
* off the given pane
|
|
*---------------------------------------------------------------------------*/
|
|
BOOL CSplitFrame::SetPaneView( int iPane, CView *pView, char *szName, int iSize)
|
|
{
|
|
BOOL bResult = m_p_oView->SetPaneView(iPane, pView, szName, iSize );
|
|
return bResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* change size of a pane
|
|
* the bBottomOrRight parameter define the direction were the place is found to
|
|
* increase pane size.
|
|
*---------------------------------------------------------------------------*/
|
|
void CSplitFrame::SetPaneSize( int iPane, int iNewSize, BOOL bBottomOrRight /*=TRUE*/ )
|
|
{
|
|
m_p_oView->m_fn_vChangePaneSize( iPane, iNewSize, bBottomOrRight);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* return the CWnd that is in the given pane
|
|
* this is not the GetActiveView, this is the active view of the CPaneFrame
|
|
* associated with the CPaneView which is in the pane
|
|
*---------------------------------------------------------------------------*/
|
|
CWnd *CSplitFrame::m_fn_p_oGetPane( int _iPane )
|
|
{
|
|
return m_p_oView->m_fn_p_oGetPane( _iPane );
|
|
}
|
|
|
|
#endif // ACTIVE_EDITOR
|