📄 controlbar.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: controlbar.cpp
// Purpose: Implementation for main controlbar classes.
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 06/09/98
// RCS-ID: $Id: controlbar.cpp,v 1.28 2006/02/11 02:03:25 MR Exp $
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <math.h>
#include <stdlib.h>
#include "wx/string.h"
#include "wx/utils.h" // import wxMin,wxMax macros
#include "wx/minifram.h"
#include "wx/fl/controlbar.h"
// import classes of default plugins
#include "wx/fl/panedrawpl.h"
#include "wx/fl/rowlayoutpl.h"
#include "wx/fl/antiflickpl.h"
#include "wx/fl/bardragpl.h"
#include "wx/fl/cbcustom.h"
#include "wx/fl/gcupdatesmgr.h" // import default updates manager class ("garbage-collecting" one)
#include "wx/fl/updatesmgr.h"
#include "wx/fl/toolwnd.h"
// These are the event IDs being initialized to a value to
// meet the new event paradigm as of wx2.3.0. Probably we
// should find a way to make these be non-global, but this
// works for right now.
wxEventType cbEVT_PL_LEFT_DOWN = wxNewEventType();
wxEventType cbEVT_PL_LEFT_UP = wxNewEventType();
wxEventType cbEVT_PL_RIGHT_DOWN = wxNewEventType();
wxEventType cbEVT_PL_RIGHT_UP = wxNewEventType();
wxEventType cbEVT_PL_MOTION = wxNewEventType();
wxEventType cbEVT_PL_LEFT_DCLICK = wxNewEventType();
wxEventType cbEVT_PL_LAYOUT_ROW = wxNewEventType();
wxEventType cbEVT_PL_RESIZE_ROW = wxNewEventType();
wxEventType cbEVT_PL_LAYOUT_ROWS = wxNewEventType();
wxEventType cbEVT_PL_INSERT_BAR = wxNewEventType();
wxEventType cbEVT_PL_RESIZE_BAR = wxNewEventType();
wxEventType cbEVT_PL_REMOVE_BAR = wxNewEventType();
wxEventType cbEVT_PL_SIZE_BAR_WND = wxNewEventType();
wxEventType cbEVT_PL_DRAW_BAR_DECOR = wxNewEventType();
wxEventType cbEVT_PL_DRAW_ROW_DECOR = wxNewEventType();
wxEventType cbEVT_PL_DRAW_PANE_DECOR = wxNewEventType();
wxEventType cbEVT_PL_DRAW_BAR_HANDLES = wxNewEventType();
wxEventType cbEVT_PL_DRAW_ROW_HANDLES = wxNewEventType();
wxEventType cbEVT_PL_DRAW_ROW_BKGROUND = wxNewEventType();
wxEventType cbEVT_PL_DRAW_PANE_BKGROUND = wxNewEventType();
wxEventType cbEVT_PL_START_BAR_DRAGGING = wxNewEventType();
wxEventType cbEVT_PL_DRAW_HINT_RECT = wxNewEventType();
wxEventType cbEVT_PL_START_DRAW_IN_AREA = wxNewEventType();
wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA = wxNewEventType();
wxEventType cbEVT_PL_CUSTOMIZE_BAR = wxNewEventType();
wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT = wxNewEventType();
wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT = wxNewEventType();
// some ascii-art, still can't get these *nice* cursors working on wx... :-(
/*
// FIXME:: see places where _gHorizCursorImg is used
static const char* _gHorizCursorImg[] =
{
"............XX....XX............",
"............XX....XX............",
"............XX....XX............",
"............XX....XX............",
"............XX....XX............",
"...X........XX....XX........X...",
"..XX........XX....XX........XX..",
".XXX........XX....XX........XXX.",
"XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
".XXX........XX....XX........XXX.",
"..XX........XX....XX........XX..",
"...X........XX....XX........X...",
"............XX....XX............",
"............XX....XX............",
"............XX....XX............",
"............XX....XX............"
};
static const char* _gVertCursorImg[] =
{
"................X...............",
"...............XXX..............",
"..............XXXXX.............",
".............XXXXXXX............",
"................X...............",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"................................",
"................................",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"................X...............",
".............XXXXXXX............",
"..............XXXXX.............",
"...............XXX..............",
"................X..............."
};
*/
// helper inline functions
static inline bool rect_contains_point( const wxRect& rect, int x, int y )
{
return ( x >= rect.x &&
y >= rect.y &&
x < rect.x + rect.width &&
y < rect.y + rect.height );
}
static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
{
if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
return 1;
return 0;
}
static inline void hide_rect( wxRect& r )
{
r.x = 32768;
r.y = 32768;
r.width = 1;
r.height = 1;
}
static inline void clip_rect_against_rect( wxRect& r1, const wxRect& r2 )
{
if ( r1.x < r2.x ||
r1.y < r2.y ||
r1.x >= r2.x + r2.width ||
r1.y >= r2.y + r2.height
)
{
hide_rect( r1 );
return;
}
else
{
if ( r1.x + r1.width > r2.x + r2.width )
r1.width = r2.x + r2.width - r1.x;
if ( r1.y + r1.height > r2.y + r2.height )
r1.height = r2.y + r2.height - r1.y;
}
}
/***** Implementation for class cbBarSpy *****/
IMPLEMENT_DYNAMIC_CLASS( cbBarSpy, wxEvtHandler )
cbBarSpy::cbBarSpy(void)
: mpLayout(0),
mpBarWnd(0)
{}
cbBarSpy::cbBarSpy( wxFrameLayout* pPanel )
: mpLayout(pPanel),
mpBarWnd(0)
{}
void cbBarSpy::SetBarWindow( wxWindow* pWnd )
{
mpBarWnd = pWnd;
}
bool cbBarSpy::ProcessEvent(wxEvent& event)
{
bool handled = wxEvtHandler::ProcessEvent( event );
int type = event.GetEventType();
if ( !handled && ( type == wxEVT_LEFT_DOWN ||
type == wxEVT_LEFT_DCLICK ) )
{
wxMouseEvent& mevent = *((wxMouseEvent*)&event);
int x = mevent.m_x;
int y = mevent.m_y;
mpBarWnd->ClientToScreen( &x, &y );
mpLayout->GetParentFrame().ScreenToClient( &x, &y );
mevent.m_x = x;
mevent.m_y = y;
// forwared not-handled event to frame-layout
if ( type == wxEVT_LEFT_DOWN )
{
//mpLayout->OnLButtonDown( mevent );
event.Skip();
}
else
mpLayout->OnLDblClick( mevent );
//event.Skip(false);
}
return handled;
}
/***** Implementation for class wxFrameLayout *****/
IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout, wxEvtHandler )
BEGIN_EVENT_TABLE( wxFrameLayout, wxEvtHandler )
EVT_PAINT ( wxFrameLayout::OnPaint )
EVT_SIZE ( wxFrameLayout::OnSize )
EVT_LEFT_DOWN ( wxFrameLayout::OnLButtonDown )
EVT_LEFT_UP ( wxFrameLayout::OnLButtonUp )
EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown )
EVT_RIGHT_UP ( wxFrameLayout::OnRButtonUp )
EVT_MOTION ( wxFrameLayout::OnMouseMove )
EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick )
EVT_IDLE ( wxFrameLayout::OnIdle )
EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground )
END_EVENT_TABLE()
// FIXME:: how to eliminate these cut&pasted constructors?
wxFrameLayout::wxFrameLayout(void)
: mpFrame ( NULL ),
mpFrameClient( NULL ),
mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ),
mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
mpPaneInFocus( NULL ),
mpLRUPane ( NULL ),
mpTopPlugin ( NULL ),
mpCaputesInput( NULL ),
mClientWndRefreshPending( false ),
mRecalcPending( true ),
mCheckFocusWhenIdle( false )
{
CreateCursors();
int i;
for ( i = 0; i != MAX_PANES; ++i )
mPanes[i] = NULL;
mFloatingOn = CanReparent();
}
wxFrameLayout::wxFrameLayout( wxWindow* pParentFrame, wxWindow* pFrameClient, bool activateNow )
: mpFrame( pParentFrame ),
mpFrameClient(pFrameClient),
mDarkPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
mLightPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
mGrayPen ( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ),
mBorderPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
mpPaneInFocus( NULL ),
mpLRUPane ( NULL ),
mFloatingOn ( true ),
mpTopPlugin ( NULL ),
mpCaputesInput( NULL ),
mClientWndRefreshPending( false ),
mRecalcPending( true ),
mCheckFocusWhenIdle( false ),
mpUpdatesMgr( NULL )
{
CreateCursors();
int i;
for ( i = 0; i != MAX_PANES; ++i )
mPanes[i] = new cbDockPane( i, this );
if ( activateNow )
{
HookUpToFrame();
// FOR NOW::
// DBG:: set RED color of frame's background for the
// prurpose of tracking engine bugs "visually"
GetParentFrame().SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE) );
}
mFloatingOn = CanReparent();
}
// NOTE:: below are the only platform-check "ifdef"s in the docking system!
bool wxFrameLayout::CanReparent()
{
#ifdef __WXMSW__
return true;
#elif defined(__WXGTK20__)
return true;
#elif defined (__WXGTK__)
//return true;
return false;
#else
return false; // reparenting is not yet supported by Motif and others
#endif
}
/*
#ifdef __WXMSW__
#inlcude "windows.h"
#endif
*/
void wxFrameLayout::ReparentWindow( wxWindow* pChild, wxWindow* pNewParent )
{
#if defined(__WXMSW__) || defined(__WXGTK20__) || defined(__WXMAC__)
pChild->Reparent(pNewParent);
return;
#elif defined(__WXGTK__) || defined(__WXX11__)
// FOR NOW:: floating with wxGtk still very buggy
return;
//pChild->ReParent( pNewParent );
//return;
#else
wxUnusedVar(pChild);
wxUnusedVar(pNewParent);
wxMessageBox( _("Sorry, docking is not supported for ports other than wxMSW, wxMac and wxGTK") );
#endif
}
void wxFrameLayout::DestroyBarWindows()
{
wxObjectList::compatibility_iterator pSpy = mBarSpyList.GetFirst();
while( pSpy )
{
cbBarSpy& spy = *((cbBarSpy*)pSpy->GetData());
if ( spy.mpBarWnd->GetEventHandler() == &spy )
spy.mpBarWnd->PopEventHandler();
delete &spy;
pSpy = pSpy->GetNext();
}
mBarSpyList.Clear();
size_t i;
for ( i = 0; i != mAllBars.Count(); ++i )
{
if ( mAllBars[i]->mpBarWnd )
{
mAllBars[i]->mpBarWnd->Destroy();
mAllBars[i]->mpBarWnd = NULL;
}
}
}
void wxFrameLayout::ShowFloatedWindows( bool show )
{
wxObjectList::compatibility_iterator pNode = mFloatedFrames.GetFirst();
while( pNode )
{
cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->GetData());
pFFrm->Show( show );
pNode = pNode->GetNext();
}
}
wxFrameLayout::~wxFrameLayout()
{
size_t i;
UnhookFromFrame();
if ( mpUpdatesMgr )
delete mpUpdatesMgr;
PopAllPlugins();
// destoy the chain of plugins from left to right
wxEvtHandler* pCur = mpTopPlugin;
if ( pCur )
while ( pCur->GetPreviousHandler() )
pCur = pCur->GetPreviousHandler();
while ( pCur )
{
wxEvtHandler* pNext = pCur->GetNextHandler();
delete pCur;
pCur = pNext;
}
// destroy contents of arrays and lists
for ( i = 0; i != MAX_PANES; ++i )
{
if ( mPanes[i] )
delete mPanes[i];
}
if ( mpHorizCursor )
delete mpHorizCursor;
if ( mpVertCursor )
delete mpVertCursor;
if ( mpNormalCursor )
delete mpNormalCursor;
if ( mpDragCursor )
delete mpDragCursor;
if ( mpNECursor )
delete mpNECursor;
wxObjectList::compatibility_iterator pSpy = mBarSpyList.GetFirst();
while( pSpy )
{
cbBarSpy& spy = *((cbBarSpy*)pSpy->GetData());
if ( spy.mpBarWnd->GetEventHandler() == &spy )
spy.mpBarWnd->PopEventHandler();
delete &spy;
pSpy = pSpy->GetNext();
}
for ( i = 0; i != mAllBars.Count(); ++i )
delete mAllBars[i];
}
void wxFrameLayout::EnableFloating( bool enable )
{
mFloatingOn = enable && CanReparent();
}
void wxFrameLayout::Activate()
{
HookUpToFrame();
RefreshNow( true );
ShowFloatedWindows( true );
}
void wxFrameLayout::Deactivate()
{
ShowFloatedWindows( false );
UnhookFromFrame();
HideBarWindows();
}
void wxFrameLayout::SetFrameClient( wxWindow* pFrameClient )
{
mpFrameClient = pFrameClient;
}
wxWindow* wxFrameLayout::GetFrameClient()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -