⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toolwnd.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        toolwnd.cpp// Purpose:     wxToolWindow implementation.// Author:      Aleksandras Gluchovas// Modified by:// Created:     06/09/98// RCS-ID:      $Id: toolwnd.cpp,v 1.19 2005/09/23 12:47:44 MR Exp $// Copyright:   (c) Aleksandras Gluchovas// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////// 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 "wx/fl/toolwnd.h"#define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)#define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)#define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.#define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.// FOR NOW:: staticstatic const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,                                                _IMG_A,_IMG_B,_IMG_C,_IMG_D,                                                _IMG_A,_IMG_B,_IMG_C,_IMG_D,                                                _IMG_A,_IMG_B,_IMG_C,_IMG_D                                              };/***** Implementation for class wxToolWindow *****/IMPLEMENT_DYNAMIC_CLASS( wxToolWindow, wxFrame)BEGIN_EVENT_TABLE( wxToolWindow, wxFrame )    EVT_PAINT    ( wxToolWindow::OnPaint )    EVT_MOTION   ( wxToolWindow::OnMotion )    EVT_LEFT_DOWN( wxToolWindow::OnLeftDown )    EVT_LEFT_UP  ( wxToolWindow::OnLeftUp )    EVT_SIZE     ( wxToolWindow::OnSize )    EVT_ERASE_BACKGROUND( wxToolWindow::OnEraseBackground )END_EVENT_TABLE()enum INTERNAL_HIT_CODES{    HITS_WND_NOTHING,    HITS_WND_CLIENT,    HITS_WND_TITLE,    HITS_WND_LEFT_EDGE,    HITS_WND_RIGHT_EDGE,    HITS_WND_TOP_EDGE,    HITS_WND_BOTTOM_EDGE,    HITS_WND_TOP_LEFT_CORNER,    HITS_WND_BOTTOM_RIGHT_CORNER,    HITS_WND_TOP_RIGHT_CORNER,    HITS_WND_BOTTOM_LEFT_CORNER};wxToolWindow::wxToolWindow()    : mpClientWnd   ( NULL ),#ifndef __WXMSW__    mTitleFont( 8, wxSWISS,  wxNORMAL, wxNORMAL ),#else    // just to simulate MS-Dev style    mTitleFont( 8, wxSWISS,  wxNORMAL, wxNORMAL, false, wxT("MS Sans Serif") ),#endif    mTitleHeight  ( 16 ),    mClntHorizGap ( 2 ),    mClntVertGap  ( 2 ),    mWndVertGap   ( 4 ),    mWndHorizGap  ( 4 ),    mButtonGap    ( 2 ),    mInTitleMargin( 4 ),    mHintBorder   ( 4 ),    mResizeStarted( false ),    mRealTimeUpdatesOn( true ),    mMTolerance   ( 5 ), // mouse-resizing tollerance    mCursorType( HITS_WND_NOTHING ),    mMouseCaptured( false ),    mpScrDc( NULL ){}wxToolWindow::~wxToolWindow(){    if ( mpScrDc ) delete mpScrDc;    for( size_t i = 0; i != mButtons.Count(); ++i )        delete mButtons[i];}void wxToolWindow::LayoutMiniButtons(){    int w,h;    GetSize( &w, &h );    int x = w - mWndHorizGap - mInTitleMargin - BTN_BOX_WIDTH;    int y = mWndVertGap + 2;    for( size_t i = 0; i != mButtons.Count(); ++i )    {        mButtons[i]->SetPos( wxPoint( x,y ) );        x-= BTN_BOX_WIDTH + mButtonGap;    }}void wxToolWindow::SetClient( wxWindow* pWnd ){    mpClientWnd = pWnd;}wxWindow* wxToolWindow::GetClient(){    return mpClientWnd;}void wxToolWindow::SetTitleFont( wxFont& font ){    mTitleFont = font;}void wxToolWindow::AddMiniButton( cbMiniButton* pBtn ){    pBtn->mpWnd = this;    mButtons.Add( pBtn );    // not necesserely now..    //LayoutMiniButtons();}void wxToolWindow::OnPaint( wxPaintEvent& WXUNUSED(event) ){    wxPaintDC pdc( this );    wxWindowDC dc( this );    int w,h;    GetSize( &w, &h );    wxBrush backGround( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID );    //dc.SetBrush( *wxLIGHT_GREY_BRUSH );    dc.SetBrush( backGround );    dc.SetPen( *wxTRANSPARENT_PEN );    int y = mWndVertGap + mTitleHeight + mClntVertGap;    dc.DrawRectangle( 0,0, w, y );                                      // Top grey part.    dc.DrawRectangle( 0,y-1, mWndHorizGap + mClntHorizGap, h - y );     // Left grey part.    dc.DrawRectangle( w - ( mWndHorizGap + mClntHorizGap ), y-1,                      mWndHorizGap + mClntHorizGap, h - y );            // Right grey part.    dc.DrawRectangle( 0, h - mWndVertGap - mClntVertGap, w, mWndVertGap + mClntVertGap ); // Bottom grey part.    // draw shades    dc.SetPen( *wxLIGHT_GREY_PEN );    dc.DrawLine( 0,0, w, 0 );    dc.DrawLine( 0,0, 0, h );    dc.SetPen( *wxWHITE_PEN );    dc.DrawLine( 1,1, w, 1 );    dc.DrawLine( 1,2, 1, h );    dc.SetPen( *wxGREY_PEN );    dc.DrawLine( w - 2, 1, w - 2, h - 1 );    dc.DrawLine( 1, h - 2, w - 2, h - 2 );    dc.SetPen( *wxBLACK_PEN );    dc.DrawLine( 0, h - 1, w, h - 1 );    dc.DrawLine( w-1, 0, w-1, h );    // fill inner area    dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( wxColour( 0,0,128 ), wxSOLID ) );    dc.DrawRectangle( mWndHorizGap, mWndVertGap, w - mWndHorizGap*2, mTitleHeight );    dc.SetFont( mTitleFont );    for( size_t i = 0; i != mButtons.Count(); ++i )        mButtons[i]->Draw( dc );    int x1 = mWndHorizGap + mClntHorizGap;    int x2 = mButtons[ mButtons.GetCount() - 1 ]->mPos.x - mClntHorizGap*2;    dc.SetClippingRegion( x1, mWndVertGap + mClntVertGap, x2 - x1, mTitleHeight );    dc.SetTextForeground( *wxWHITE );    dc.SetBackgroundMode(  wxTRANSPARENT );    dc.DrawText( GetTitle(), mWndHorizGap + 2, mWndVertGap + 1 );}void wxToolWindow::GetScrWindowRect( wxRect& r ){    int x,y;    GetPosition(&x,&y);    int w,h;    GetSize( &w, &h );    r.x = x; r.y = y;    r.width = w; r.height = h;}void wxToolWindow::GetScrMousePos( wxMouseEvent& event, wxPoint& pos ){    int x = event.m_x, y = event.m_y;    ClientToScreen( &x, &y );    pos.x = x; pos.y = y;}int wxToolWindow::HitTestWindow( wxMouseEvent& event ){    wxPoint pos;    wxRect r;    GetScrMousePos( event, pos );    GetScrWindowRect( r );    int k = mMTolerance;    if ( !( pos.x >= r.x && pos.y >= r.y &&            pos.x < r.x + r.width &&            pos.y < r.y + r.height )       )        return HITS_WND_NOTHING;    if ( pos.y <= r.y + k )    {        if ( pos.x < r.x + k*2 )            return HITS_WND_TOP_LEFT_CORNER;        else        {            if ( pos.x >= r.x + r.width - k*2 )                return HITS_WND_TOP_RIGHT_CORNER;            else                return HITS_WND_TOP_EDGE;        }    }    else    {        if ( pos.y >= r.y + r.height - k )        {            if ( pos.x < r.x + k*2 )                return HITS_WND_BOTTOM_LEFT_CORNER;            else            {                if ( pos.x > r.x + r.width - k*2 )                    return HITS_WND_BOTTOM_RIGHT_CORNER;                else                    return HITS_WND_BOTTOM_EDGE;            }        }        else        {            if ( pos.x <= r.x + k )                return HITS_WND_LEFT_EDGE;            else            {                if ( pos.x >= r.x + r.width - k )                    return HITS_WND_RIGHT_EDGE;                else                {                    if ( pos.y <= r.y + mWndVertGap + mTitleHeight + mClntVertGap )                        return HITS_WND_TITLE;                    else                        return HITS_WND_CLIENT;                }            }        }    }}void wxToolWindow::DrawHintRect( const wxRect& r ){    // BUG BUG BUG (wx):: somehow stippled brush works only    //                    when the bitmap created on stack, not    //                    as a member of the class    int prevLF = mpScrDc->GetLogicalFunction();    mpScrDc->SetLogicalFunction( wxXOR );    wxBitmap checker( (const char*)_gCheckerImg, 8,8 );    wxBrush checkerBrush( checker );    mpScrDc->SetPen( *wxTRANSPARENT_PEN );    mpScrDc->SetBrush( checkerBrush );    int half = mHintBorder / 2;    mpScrDc->DrawRectangle( r.x - half, r.y - half,                            r.width + 2*half, mHintBorder );    mpScrDc->DrawRectangle( r.x - half, r.y + r.height - half,                            r.width + 2*half, mHintBorder );    mpScrDc->DrawRectangle( r.x - half, r.y + half - 1,                            mHintBorder, r.height - 2*half + 2);    mpScrDc->DrawRectangle( r.x + r.width - half,                            r.y + half - 1,                            mHintBorder, r.height - 2*half + 2);    mpScrDc->SetBrush( wxNullBrush );    mpScrDc->SetLogicalFunction( prevLF );}void wxToolWindow::SetHintCursor( int type ){    if ( mResizeStarted )        return;    if ( type == HITS_WND_NOTHING || type == HITS_WND_CLIENT )    {        // the cursor is out of window - reset to arrow        if ( mMouseCaptured )        {            ReleaseMouse();            mMouseCaptured = false;        }        SetCursor( wxCURSOR_ARROW );        mCursorType = type;        return;    }    // did the cursor actually changed?    if ( type != mCursorType )    {        mCursorType = type;        switch ( type )        {            case HITS_WND_LEFT_EDGE   : SetCursor( wxCURSOR_SIZEWE ); break;            case HITS_WND_RIGHT_EDGE  : SetCursor( wxCURSOR_SIZEWE ); break;            case HITS_WND_TOP_EDGE    : SetCursor( wxCURSOR_SIZENS ); break;            case HITS_WND_BOTTOM_EDGE : SetCursor( wxCURSOR_SIZENS ); break;            case HITS_WND_TOP_LEFT_CORNER     : SetCursor( wxCURSOR_SIZENWSE ); break;            case HITS_WND_BOTTOM_RIGHT_CORNER : SetCursor( wxCURSOR_SIZENWSE ); break;            case HITS_WND_TOP_RIGHT_CORNER    : SetCursor( wxCURSOR_SIZENESW ); break;            case HITS_WND_BOTTOM_LEFT_CORNER  : SetCursor( wxCURSOR_SIZENESW ); break;            case HITS_WND_TITLE  : SetCursor( wxCURSOR_ARROW ); break;            case HITS_WND_CLIENT : SetCursor( wxCURSOR_ARROW ); break;            default: break;        }        if (mMouseCaptured)        {            mMouseCaptured = false;            ReleaseMouse();        }    }    if ( !mMouseCaptured )    {        mMouseCaptured = true;        CaptureMouse();    }}#define FL_INFINITY 32768static inline void clip_to( int& value, long from, long till ){    if ( value < from )        value = from;    if ( value > till )        value = till;}void wxToolWindow::AdjustRectPos( const wxRect& original, const wxSize& newDim, wxRect& newRect ){    if ( mCursorType == HITS_WND_TOP_EDGE ||         mCursorType == HITS_WND_TOP_LEFT_CORNER )    {        newRect.x = original.x + original.width  - newDim.x;        newRect.y = original.y + original.height - newDim.y;    }    else    if ( mCursorType == HITS_WND_LEFT_EDGE ||         mCursorType == HITS_WND_BOTTOM_LEFT_CORNER )    {        newRect.x = original.x + original.width  - newDim.x;        newRect.y = original.y;    }    else    if ( mCursorType == HITS_WND_RIGHT_EDGE ||         mCursorType == HITS_WND_TOP_RIGHT_CORNER )    {        newRect.x = original.x;        newRect.y = original.y + original.height - newDim.y;    }    else    if ( mCursorType == HITS_WND_BOTTOM_EDGE ||         mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER )    {        newRect.x = original.x;        newRect.y = original.y;    }    newRect.width  = newDim.x;    newRect.height = newDim.y;}void wxToolWindow::CalcResizedRect( wxRect& rect, wxPoint& delta, const wxSize& minDim ){    // Microsoft's rect-coordinates are best suited    // for the case of corner-clipping    int left   = mInitialRect.x;    int top    = mInitialRect.y;    int right  = mInitialRect.x + mInitialRect.width;    int bottom = mInitialRect.y + mInitialRect.height;    // constraint delta edge is dragged    switch ( mCursorType )    {        case HITS_WND_LEFT_EDGE   : delta.y = 0; break;        case HITS_WND_RIGHT_EDGE  : delta.y = 0; break;        case HITS_WND_TOP_EDGE    : delta.x = 0; break;        case HITS_WND_BOTTOM_EDGE : delta.x = 0; break;        default: break;    }    if ( mCursorType == HITS_WND_TOP_EDGE ||         mCursorType == HITS_WND_TOP_LEFT_CORNER )    {        left += delta.x;        top  += delta.y;        clip_to( left, -FL_INFINITY, mInitialRect.x + mInitialRect.width  - minDim.x  );        clip_to( top,  -FL_INFINITY, mInitialRect.y + mInitialRect.height - minDim.y );    }    else    if ( mCursorType == HITS_WND_LEFT_EDGE ||         mCursorType == HITS_WND_BOTTOM_LEFT_CORNER )    {        left   += delta.x;        bottom += delta.y;        clip_to( left,    -FL_INFINITY, mInitialRect.x + mInitialRect.width  - minDim.x  );        clip_to( bottom,  mInitialRect.y + minDim.y, FL_INFINITY );    }    else    if ( mCursorType == HITS_WND_RIGHT_EDGE ||        mCursorType == HITS_WND_TOP_RIGHT_CORNER )    {        right += delta.x;        top   += delta.y;        clip_to( right, mInitialRect.x + minDim.x, FL_INFINITY );        clip_to( top,   -FL_INFINITY, mInitialRect.y + mInitialRect.height - minDim.y );    }    else    if ( mCursorType == HITS_WND_BOTTOM_EDGE ||         mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER )    {        right  += delta.x;        bottom += delta.y;        clip_to( right,  mInitialRect.x + minDim.x,  FL_INFINITY );        clip_to( bottom, mInitialRect.y + minDim.y, FL_INFINITY );    }    else    {        wxFAIL_MSG( _T("what did the cursor hit?") );    }    rect.x = left;    rect.y = top;    rect.width  = right - left;    rect.height = bottom - top;}wxSize wxToolWindow::GetMinimalWndDim(){    return wxSize( (mWndHorizGap + mClntHorizGap)*2 + BTN_BOX_WIDTH*4,                   (mWndVertGap  + mClntVertGap )*2 + mTitleHeight );}void wxToolWindow::OnMotion( wxMouseEvent& event ){    if ( !mResizeStarted )    {        for( size_t i = 0; i != mButtons.Count(); ++i )            mButtons[i]->OnMotion( wxPoint( event.m_x, event.m_y ) );        SetHintCursor( HitTestWindow( event ) );        return;    }    wxPoint pos;    GetScrMousePos( event, pos );    if ( mCursorType == HITS_WND_TITLE )    {        int w,h;        GetSize( &w, &h );        SetSize( mInitialRect.x + pos.x - mDragOrigin.x,                 mInitialRect.y + pos.y - mDragOrigin.y,                 w,h, 0 );    }    else    {        wxPoint delta( pos.x - mDragOrigin.x, pos.y - mDragOrigin.y );        wxRect newRect;        wxSize minDim = GetMinimalWndDim();        CalcResizedRect( newRect, delta, minDim );        wxSize borderDim( ( mWndHorizGap + mClntHorizGap )*2,                          ( mWndVertGap  + mClntVertGap  )*2 + mTitleHeight );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -