grid.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,252 行 · 第 1/5 页
CPP
2,252 行
///////////////////////////////////////////////////////////////////////////
// Name: generic/grid.cpp
// Purpose: wxGrid and related classes
// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
// Modified by: Robin Dunn, Vadim Zeitlin
// Created: 1/08/1999
// RCS-ID: $Id: grid.cpp,v 1.345.2.3 2006/03/07 14:50:50 JS Exp $
// Copyright: (c) Michael Bedward (mbedward@ozemail.com.au)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "grid.h"
#endif
// For compilers that support precompilatixon, includes "wx/wx.h".
#include "wx/wxprec.h"
#include "wx/defs.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_GRID
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/dcclient.h"
#include "wx/settings.h"
#include "wx/log.h"
#include "wx/textctrl.h"
#include "wx/checkbox.h"
#include "wx/combobox.h"
#include "wx/valtext.h"
#include "wx/intl.h"
#endif
#include "wx/textfile.h"
#include "wx/spinctrl.h"
#include "wx/tokenzr.h"
#include "wx/renderer.h"
#include "wx/grid.h"
#include "wx/generic/gridsel.h"
#if defined(__WXMOTIF__)
#define WXUNUSED_MOTIF(identifier) WXUNUSED(identifier)
#else
#define WXUNUSED_MOTIF(identifier) identifier
#endif
#if defined(__WXGTK__)
#define WXUNUSED_GTK(identifier) WXUNUSED(identifier)
#else
#define WXUNUSED_GTK(identifier) identifier
#endif
// Required for wxIs... functions
#include <ctype.h>
// ----------------------------------------------------------------------------
// array classes
// ----------------------------------------------------------------------------
WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs,
class WXDLLIMPEXP_ADV);
struct wxGridCellWithAttr
{
wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_)
: coords(row, col), attr(attr_)
{
}
~wxGridCellWithAttr()
{
attr->DecRef();
}
wxGridCellCoords coords;
wxGridCellAttr *attr;
// Cannot do this:
// DECLARE_NO_COPY_CLASS(wxGridCellWithAttr)
// without rewriting the macros, which require a public copy constructor.
};
WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray,
class WXDLLIMPEXP_ADV);
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxGridCellCoordsArray)
WX_DEFINE_OBJARRAY(wxGridCellWithAttrArray)
// ----------------------------------------------------------------------------
// events
// ----------------------------------------------------------------------------
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_BEGIN_DRAG)
DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE)
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE)
DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT)
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE)
DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL)
DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN)
DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN)
DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_CREATED)
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxWindow
{
public:
wxGridRowLabelWindow() { m_owner = (wxGrid *)NULL; }
wxGridRowLabelWindow( wxGrid *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size );
private:
wxGrid *m_owner;
void OnPaint( wxPaintEvent& event );
void OnMouseEvent( wxMouseEvent& event );
void OnMouseWheel( wxMouseEvent& event );
void OnKeyDown( wxKeyEvent& event );
void OnKeyUp( wxKeyEvent& );
void OnChar( wxKeyEvent& );
DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow)
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxGridRowLabelWindow)
};
class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxWindow
{
public:
wxGridColLabelWindow() { m_owner = (wxGrid *)NULL; }
wxGridColLabelWindow( wxGrid *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size );
private:
wxGrid *m_owner;
void OnPaint( wxPaintEvent &event );
void OnMouseEvent( wxMouseEvent& event );
void OnMouseWheel( wxMouseEvent& event );
void OnKeyDown( wxKeyEvent& event );
void OnKeyUp( wxKeyEvent& );
void OnChar( wxKeyEvent& );
DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow)
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxGridColLabelWindow)
};
class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxWindow
{
public:
wxGridCornerLabelWindow() { m_owner = (wxGrid *)NULL; }
wxGridCornerLabelWindow( wxGrid *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size );
private:
wxGrid *m_owner;
void OnMouseEvent( wxMouseEvent& event );
void OnMouseWheel( wxMouseEvent& event );
void OnKeyDown( wxKeyEvent& event );
void OnKeyUp( wxKeyEvent& );
void OnChar( wxKeyEvent& );
void OnPaint( wxPaintEvent& event );
DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow)
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow)
};
class WXDLLIMPEXP_ADV wxGridWindow : public wxWindow
{
public:
wxGridWindow()
{
m_owner = (wxGrid *)NULL;
m_rowLabelWin = (wxGridRowLabelWindow *)NULL;
m_colLabelWin = (wxGridColLabelWindow *)NULL;
}
wxGridWindow( wxGrid *parent,
wxGridRowLabelWindow *rowLblWin,
wxGridColLabelWindow *colLblWin,
wxWindowID id, const wxPoint &pos, const wxSize &size );
~wxGridWindow(){}
void ScrollWindow( int dx, int dy, const wxRect *rect );
wxGrid* GetOwner() { return m_owner; }
private:
wxGrid *m_owner;
wxGridRowLabelWindow *m_rowLabelWin;
wxGridColLabelWindow *m_colLabelWin;
void OnPaint( wxPaintEvent &event );
void OnMouseWheel( wxMouseEvent& event );
void OnMouseEvent( wxMouseEvent& event );
void OnKeyDown( wxKeyEvent& );
void OnKeyUp( wxKeyEvent& );
void OnChar( wxKeyEvent& );
void OnEraseBackground( wxEraseEvent& );
void OnFocus( wxFocusEvent& );
DECLARE_DYNAMIC_CLASS(wxGridWindow)
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxGridWindow)
};
class wxGridCellEditorEvtHandler : public wxEvtHandler
{
public:
wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor)
: m_grid(grid),
m_editor(editor),
m_inSetFocus(false)
{
}
void OnKillFocus(wxFocusEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnChar(wxKeyEvent& event);
void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; }
private:
wxGrid* m_grid;
wxGridCellEditor* m_editor;
// Work around the fact that a focus kill event can be sent to
// a combobox within a set focus event.
bool m_inSetFocus;
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler)
};
IMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler)
BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler )
EVT_KILL_FOCUS( wxGridCellEditorEvtHandler::OnKillFocus )
EVT_KEY_DOWN( wxGridCellEditorEvtHandler::OnKeyDown )
EVT_CHAR( wxGridCellEditorEvtHandler::OnChar )
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// the internal data representation used by wxGridCellAttrProvider
// ----------------------------------------------------------------------------
// this class stores attributes set for cells
class WXDLLIMPEXP_ADV wxGridCellAttrData
{
public:
void SetAttr(wxGridCellAttr *attr, int row, int col);
wxGridCellAttr *GetAttr(int row, int col) const;
void UpdateAttrRows( size_t pos, int numRows );
void UpdateAttrCols( size_t pos, int numCols );
private:
// searches for the attr for given cell, returns wxNOT_FOUND if not found
int FindIndex(int row, int col) const;
wxGridCellWithAttrArray m_attrs;
};
// this class stores attributes set for rows or columns
class WXDLLIMPEXP_ADV wxGridRowOrColAttrData
{
public:
// empty ctor to suppress warnings
wxGridRowOrColAttrData() { }
~wxGridRowOrColAttrData();
void SetAttr(wxGridCellAttr *attr, int rowOrCol);
wxGridCellAttr *GetAttr(int rowOrCol) const;
void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols );
private:
wxArrayInt m_rowsOrCols;
wxArrayAttrs m_attrs;
};
// NB: this is just a wrapper around 3 objects: one which stores cell
// attributes, and 2 others for row/col ones
class WXDLLIMPEXP_ADV wxGridCellAttrProviderData
{
public:
wxGridCellAttrData m_cellAttrs;
wxGridRowOrColAttrData m_rowAttrs,
m_colAttrs;
};
// ----------------------------------------------------------------------------
// data structures used for the data type registry
// ----------------------------------------------------------------------------
struct wxGridDataTypeInfo
{
wxGridDataTypeInfo(const wxString& typeName,
wxGridCellRenderer* renderer,
wxGridCellEditor* editor)
: m_typeName(typeName), m_renderer(renderer), m_editor(editor)
{ }
~wxGridDataTypeInfo()
{
wxSafeDecRef(m_renderer);
wxSafeDecRef(m_editor);
}
wxString m_typeName;
wxGridCellRenderer* m_renderer;
wxGridCellEditor* m_editor;
DECLARE_NO_COPY_CLASS(wxGridDataTypeInfo)
};
WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray,
class WXDLLIMPEXP_ADV);
class WXDLLIMPEXP_ADV wxGridTypeRegistry
{
public:
wxGridTypeRegistry() {}
~wxGridTypeRegistry();
void RegisterDataType(const wxString& typeName,
wxGridCellRenderer* renderer,
wxGridCellEditor* editor);
// find one of already registered data types
int FindRegisteredDataType(const wxString& typeName);
// try to FindRegisteredDataType(), if this fails and typeName is one of
// standard typenames, register it and return its index
int FindDataType(const wxString& typeName);
// try to FindDataType(), if it fails see if it is not one of already
// registered data types with some params in which case clone the
// registered data type and set params for it
int FindOrCloneDataType(const wxString& typeName);
wxGridCellRenderer* GetRenderer(int index);
wxGridCellEditor* GetEditor(int index);
private:
wxGridDataTypeInfoArray m_typeinfo;
};
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
#ifndef WXGRID_DRAW_LINES
#define WXGRID_DRAW_LINES 1
#endif
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
//#define DEBUG_ATTR_CACHE
#ifdef DEBUG_ATTR_CACHE
static size_t gs_nAttrCacheHits = 0;
static size_t gs_nAttrCacheMisses = 0;
#endif // DEBUG_ATTR_CACHE
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
// scroll line size
// TODO: this doesn't work at all, grid cells have different sizes and approx
// calculations don't work as because of the size mismatch scrollbars
// sometimes fail to be shown when they should be or vice versa
//
// The scroll bars may be a little flakey once in a while, but that is
// surely much less horrible than having scroll lines of only 1!!!
// -- Robin
//
// Well, it's still seriously broken so it might be better but needs
// fixing anyhow
// -- Vadim
static const size_t GRID_SCROLL_LINE_X = 15; // 1;
static const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
// the size of hash tables used a bit everywhere (the max number of elements
// in these hash tables is the number of rows/columns)
static const int GRID_HASH_SIZE = 100;
#if 0
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
static inline int GetScrollX(int x)
{
return (x + GRID_SCROLL_LINE_X - 1) / GRID_SCROLL_LINE_X;
}
static inline int GetScrollY(int y)
{
return (y + GRID_SCROLL_LINE_Y - 1) / GRID_SCROLL_LINE_Y;
}
#endif
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?