sashwin.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 712 行 · 第 1/2 页
CPP
712 行
/////////////////////////////////////////////////////////////////////////////
// Name: sashwin.cpp
// Purpose: wxSashWindow implementation. A sash window has an optional
// sash on each edge, allowing it to be dragged. An event
// is generated when the sash is released.
// Author: Julian Smart
// Modified by:
// Created: 01/02/97
// RCS-ID: $Id: sashwin.cpp,v 1.46 2004/12/14 20:41:53 ABX Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "sashwin.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_SASH
#ifndef WX_PRECOMP
#include "wx/dialog.h"
#include "wx/frame.h"
#include "wx/settings.h"
#endif
#include "wx/math.h"
#include <stdlib.h>
#include "wx/dcscreen.h"
#include "wx/sashwin.h"
#include "wx/laywin.h"
DEFINE_EVENT_TYPE(wxEVT_SASH_DRAGGED)
IMPLEMENT_DYNAMIC_CLASS(wxSashWindow, wxWindow)
IMPLEMENT_DYNAMIC_CLASS(wxSashEvent, wxCommandEvent)
BEGIN_EVENT_TABLE(wxSashWindow, wxWindow)
EVT_PAINT(wxSashWindow::OnPaint)
EVT_SIZE(wxSashWindow::OnSize)
EVT_MOUSE_EVENTS(wxSashWindow::OnMouseEvent)
#if defined( __WXMSW__ ) || defined( __WXMAC__)
EVT_SET_CURSOR(wxSashWindow::OnSetCursor)
#endif // wxMSW
END_EVENT_TABLE()
bool wxSashWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name)
{
return wxWindow::Create(parent, id, pos, size, style, name);
}
wxSashWindow::~wxSashWindow()
{
delete m_sashCursorWE;
delete m_sashCursorNS;
}
void wxSashWindow::Init()
{
m_draggingEdge = wxSASH_NONE;
m_dragMode = wxSASH_DRAG_NONE;
m_oldX = 0;
m_oldY = 0;
m_firstX = 0;
m_firstY = 0;
m_borderSize = 3;
m_extraBorderSize = 0;
m_minimumPaneSizeX = 0;
m_minimumPaneSizeY = 0;
m_maximumPaneSizeX = 10000;
m_maximumPaneSizeY = 10000;
m_sashCursorWE = new wxCursor(wxCURSOR_SIZEWE);
m_sashCursorNS = new wxCursor(wxCURSOR_SIZENS);
m_mouseCaptured = false;
m_currentCursor = NULL;
// Eventually, we'll respond to colour change messages
InitColours();
}
void wxSashWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
DrawBorders(dc);
DrawSashes(dc);
}
void wxSashWindow::OnMouseEvent(wxMouseEvent& event)
{
wxCoord x, y;
event.GetPosition(&x, &y);
wxSashEdgePosition sashHit = SashHitTest(x, y);
if (event.LeftDown())
{
CaptureMouse();
m_mouseCaptured = true;
if ( sashHit != wxSASH_NONE )
{
// Required for X to specify that
// that we wish to draw on top of all windows
// - and we optimise by specifying the area
// for creating the overlap window.
// Find the first frame or dialog and use this to specify
// the area to draw on.
wxWindow* parent = this;
while (parent && !parent->IsKindOf(CLASSINFO(wxDialog)) &&
!parent->IsKindOf(CLASSINFO(wxFrame)))
parent = parent->GetParent();
wxScreenDC::StartDrawingOnTop(parent);
// We don't say we're dragging yet; we leave that
// decision for the Dragging() branch, to ensure
// the user has dragged a little bit.
m_dragMode = wxSASH_DRAG_LEFT_DOWN;
m_draggingEdge = sashHit;
m_firstX = x;
m_firstY = y;
if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) )
{
if (m_currentCursor != m_sashCursorWE)
{
SetCursor(*m_sashCursorWE);
}
m_currentCursor = m_sashCursorWE;
}
else
{
if (m_currentCursor != m_sashCursorNS)
{
SetCursor(*m_sashCursorNS);
}
m_currentCursor = m_sashCursorNS;
}
}
}
else if ( event.LeftUp() && m_dragMode == wxSASH_DRAG_LEFT_DOWN )
{
// Wasn't a proper drag
if (m_mouseCaptured)
ReleaseMouse();
m_mouseCaptured = false;
wxScreenDC::EndDrawingOnTop();
m_dragMode = wxSASH_DRAG_NONE;
m_draggingEdge = wxSASH_NONE;
}
else if (event.LeftUp() && m_dragMode == wxSASH_DRAG_DRAGGING)
{
// We can stop dragging now and see what we've got.
m_dragMode = wxSASH_DRAG_NONE;
if (m_mouseCaptured)
ReleaseMouse();
m_mouseCaptured = false;
// Erase old tracker
DrawSashTracker(m_draggingEdge, m_oldX, m_oldY);
// End drawing on top (frees the window used for drawing
// over the screen)
wxScreenDC::EndDrawingOnTop();
int w, h;
GetSize(&w, &h);
int xp, yp;
GetPosition(&xp, &yp);
wxSashEdgePosition edge = m_draggingEdge;
m_draggingEdge = wxSASH_NONE;
wxRect dragRect;
wxSashDragStatus status = wxSASH_STATUS_OK;
// the new height and width of the window - if -1, it didn't change
int newHeight = wxDefaultCoord,
newWidth = wxDefaultCoord;
// NB: x and y may be negative and they're relative to the sash window
// upper left corner, while xp and yp are expressed in the parent
// window system of coordinates, so adjust them! After this
// adjustment, all coordinates are relative to the parent window.
y += yp;
x += xp;
switch (edge)
{
case wxSASH_TOP:
if ( y > yp + h )
{
// top sash shouldn't get below the bottom one
status = wxSASH_STATUS_OUT_OF_RANGE;
}
else
{
newHeight = h - (y - yp);
}
break;
case wxSASH_BOTTOM:
if ( y < yp )
{
// bottom sash shouldn't get above the top one
status = wxSASH_STATUS_OUT_OF_RANGE;
}
else
{
newHeight = y - yp;
}
break;
case wxSASH_LEFT:
if ( x > xp + w )
{
// left sash shouldn't get beyond the right one
status = wxSASH_STATUS_OUT_OF_RANGE;
}
else
{
newWidth = w - (x - xp);
}
break;
case wxSASH_RIGHT:
if ( x < xp )
{
// and the right sash, finally, shouldn't be beyond the
// left one
status = wxSASH_STATUS_OUT_OF_RANGE;
}
else
{
newWidth = x - xp;
}
break;
case wxSASH_NONE:
// can this happen at all?
break;
}
if ( newHeight == wxDefaultCoord )
{
// didn't change
newHeight = h;
}
else
{
// make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range
newHeight = wxMax(newHeight, m_minimumPaneSizeY);
newHeight = wxMin(newHeight, m_maximumPaneSizeY);
}
if ( newWidth == wxDefaultCoord )
{
// didn't change
newWidth = w;
}
else
{
// make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range
newWidth = wxMax(newWidth, m_minimumPaneSizeX);
newWidth = wxMin(newWidth, m_maximumPaneSizeX);
}
dragRect = wxRect(x, y, newWidth, newHeight);
wxSashEvent event(GetId(), edge);
event.SetEventObject(this);
event.SetDragStatus(status);
event.SetDragRect(dragRect);
GetEventHandler()->ProcessEvent(event);
}
else if ( event.LeftUp() )
{
if (m_mouseCaptured)
ReleaseMouse();
m_mouseCaptured = false;
}
else if (event.Moving() && !event.Dragging())
{
// Just change the cursor if required
if ( sashHit != wxSASH_NONE )
{
if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) )
{
if (m_currentCursor != m_sashCursorWE)
{
SetCursor(*m_sashCursorWE);
}
m_currentCursor = m_sashCursorWE;
}
else
{
if (m_currentCursor != m_sashCursorNS)
{
SetCursor(*m_sashCursorNS);
}
m_currentCursor = m_sashCursorNS;
}
}
else
{
SetCursor(wxNullCursor);
m_currentCursor = NULL;
}
}
else if ( event.Dragging() &&
((m_dragMode == wxSASH_DRAG_DRAGGING) ||
(m_dragMode == wxSASH_DRAG_LEFT_DOWN)) )
{
if ( (m_draggingEdge == wxSASH_LEFT) || (m_draggingEdge == wxSASH_RIGHT) )
{
if (m_currentCursor != m_sashCursorWE)
{
SetCursor(*m_sashCursorWE);
}
m_currentCursor = m_sashCursorWE;
}
else
{
if (m_currentCursor != m_sashCursorNS)
{
SetCursor(*m_sashCursorNS);
}
m_currentCursor = m_sashCursorNS;
}
if (m_dragMode == wxSASH_DRAG_LEFT_DOWN)
{
m_dragMode = wxSASH_DRAG_DRAGGING;
DrawSashTracker(m_draggingEdge, x, y);
}
else
{
if ( m_dragMode == wxSASH_DRAG_DRAGGING )
{
// Erase old tracker
DrawSashTracker(m_draggingEdge, m_oldX, m_oldY);
// Draw new one
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?