propgrid.cpp

来自「这是一个GPS相关的程序」· C++ 代码 · 共 2,266 行 · 第 1/5 页

CPP
2,266
字号

// For wxMSW cursor consistency, we must do mouse capturing even
// when using custom controls.

#define BEGIN_MOUSE_CAPTURE \
    if ( !(m_iFlags & wxPG_FL_MOUSE_CAPTURED) ) \
    { \
        CaptureMouse(); \
        m_iFlags |= wxPG_FL_MOUSE_CAPTURED; \
    }

#define END_MOUSE_CAPTURE \
    if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) \
    { \
        ReleaseMouse(); \
        m_iFlags &= ~(wxPG_FL_MOUSE_CAPTURED); \
    }

// -----------------------------------------------------------------------
// NOTES
// -----------------------------------------------------------------------

//
// -----------------------------------------------------------------------
// TODO
// -----------------------------------------------------------------------
//

//
// For Next Release:
// * Third "unspecified" state to bool properties.
//
// Maybe later:
// * Fix MSW spinctrl indentation (using old tc indent fix)?
// * IntProperty min/max (automatic use: validator, spinctrl).
// * Python: Proper refcounting hack (regarding double incref)?
// * Python: Crash if not imported in global scope?
// * GetPropertyValue() to return Null wxVariant if the property value is
//   unspecified (uncomment code in GetValueAsVariant).
// * Key interceptor docs (remember GetGrid!).
// * Traditional wxValidator mode?.
// * wxPG_EX_ALTERNATE_KEYS?
// * Make various wxPropertyGridState methods virtual (SetPropertyValues).
// * Add pImpl.
// * GetPropertyAttribute
// * Fix Python SetValues Freeze-Thaw (regarding autofill=True).
// * Double-buffering to checkbox.
// * Increase consistency of OnResize (need better testing code/procedure).
//   One potential solution is to use, as someone suggested, a large panel on
//   wxScrolledWindow.
// * If wxParentProperty is loaded from a text source, its value should
//   be set *after* all children are inserted.
// * Enable font images?
// * After 1.0.x compatibility removed, drop itemcount argument support.
//
// 1.3 Branch:
// * onevent wnd always actual control, never clipper.
// * Custom values (one of which is Unspecified). Up to 255, use string table
//   in property grid for relevant displayed strings.
// * Maybe have wxPG_EX_PROCESS_EVENTS_IMMEDIATELY behaviour as default (and non-
//   optional).
// * Move to different directory style to enable CVS usage.
// * Integrate the flexible MVC grid backend.
// * wxPGId == wxPGProperty*
// * wxSize, wxDateTime, wxPoint returned as values instead of const Foo&
//   (so that empty values can be returned on invalid property).
// * Get rid of wxPG_COMPATIBILITY_1_0_0s.
// * Classnames = property names
//   Construction requires new then probably. The only way around
//   this would be a way too messy copying system.
// * IsPropertyXXX to const?
// * If child changed, send changed events for all related parents *as well*.
// * wxPGNameStr -> const wxString& (but retain typedef).
// * wxPGId -> wxPGProperty* (but retain typedef).
// * Change wxPG_SUBID1 etc to 1,2,3...
// * Have wxPG_EX_GREY_LABEL_WHEN_DISABLED as default.
// * wxVariant values.
//   * Would not eliminate need for DoSetValue and GetValue in
//     all cases (but would in most).
//   * Value type would do ValueToString and ValueToInt conversion.
//     Property ptr would be given as arg, so that int value type
//     could convert itself into a choice string at value's index.
// * Images in front of labels.
// * SetPropertyBackgroundColour instead of SetPropertyColour.
// * Replace SetAttribute with DoSetAttribute, and add SetAttribute as
//   user-usable method (currently there is only SetAttrib).
// * Get rid of priority system/compactor button (with compatibility defines,
//   however).
// * Real property attribute system.
// * String attribute names (old defines can be set to strings, so the
//   compatibility is kept).
// * Deprecate IsModified (in favour of IsPropertyModified).
// * Deprecate Disable.
// * HitTest.
// * SetPropertyTextColour.
// * Abstract wxPGEditorDialog scheme (longstringproperty and arraystringproperty
//   to support it, at the least). Probably needs an adapter class
//   (for validator support and such).
// * Replace FROM_STATE macros (but remember, it is redefined just prior to
//   state methods!!!).
// * wxPG_INVALID_VALUE to equal INT_MIN. Or not? Does it matter?
//
// High Priority but Difficult to implement or justify:
// * TAB should visit trigger buttons as well (but requires that wxButton or
//   its usage is properly fixed to support key event tracking.
// * Put kbd focus rectangle to check box, but only when focus really comes
//   from kbd.
// * Child priority system more consistent (ie. wxPGPWC vs wxPP vs wxCP)
// * Consider: move (some of the) example properties to headers.
// * Finalize: Font property images (drop down could use them as well, and even
//   in more useful manner).
// * wxMSW: Scrollbar freeze after mode switch (did resizing before that).
//
// For Some of the Next Releases:
// * Consider: Semi-unfocus on when clicking (l+r) on empty space.
// * Consider: Match system font size in grid.
//   Problem: There is no preferred font point size detection.
// * Multiple delimiters for string tokenizers (e.g. ';' in addition to ',').
// * Temporary object file etc folder and file removal on install and uninstall.
// * Consider: Further additions to wxPropertyContainerMethods
//   (virtual Insert, Delete and DrawItemAndChildren, and then methods
//   that need them). This could reduce size of wxPropertyGridManager
//   code.
// * Consider: three-argument wxEnumProperty (choices would be added
//     with AddPropertyChoice). Already has this, but with docs too.
// * Error/Warning popups (preferably a balloon tooltip on WinNT-based OS).
// * Consider adding optional images in front of property label.
// * Improve string editor dialog (but how?).
//
// Bug Fixes:
// * wxGTK, no cc: Right-click doesn't occur if right-clicked on control.
// * wxGTK, no cc: TAB-based editor browsing ceases sometimes (try 2nd page, until
//   two disabled boolprops).
//
// Medium Priority:
// * wxPropertyGridManager's missing methods:
//   GetLastProperty.
// * Adding items when focused is no-no.
// * Properly fix DoGetBestSize (both controls). How? It is called but
//   result is probably somehow interpreted incorrectly.
//
// To Consider:
// * Simple checkbox: Background clear unaligned (see with grey colour scheme).
//   Problem: It is caused by the MSW checkmark drawing background clear.
// * Remove hover support to lighten some code (no tooltips, then).
//   Would basicly eliminate need for visibility cache (get first visible
//   instead viscache refresh and find items around it).
// * Custom image horizontal size increment in relation to line height.
//   Feb-13-2005: Only real help if people use really big ( ptsz>12 ) fonts.
//   So this is real low priority.
// * At some occasions, maybe use FindOrCreatePen and FindOrCreateBrush.
//   Feb-13-2005: More bloat for marginal gains.
// * Key event forwarding (use ex flag to mark that).
//   Feb-13-2005: Really needed?
// * Visual state saving (which items are expanded and which collapsed,
//   which mode is selected).
//   Feb-13-2005: More bloat?
// * Manager: SetCustomModeBitmaps. Call before toolbar is actually created.
//   Feb-13-2005: More bloat?
// * More drop-down editors (for wxLongStringProperty etc.) instead of modal dialogs.
//   Problem: complex, multi-sub-control popups do not work yet (will they ever work?).
//
// Low Priority:
// * wxPropertyGridManager::SetFont.
// * Basic context menu with Reset() and checkable Show Description that toggle the help box.
// * wxCustomEnumProperty - Allows user to set the image as well.
// * GetItemAtY() to use binary search.
// * Preparations for wxPGProperty direct usage.
// * Refine dialog-position auto-generator.
// * Maybe different colour lines between categories (like light grey ones in .NET).
//   (though I don't think its that elegant).
// * wxGTK1: Multichoice can't get value correctly.
// * wxGTK1: Control(s) disapper after:
//     Splitter centering.
//     Collapse expand.
//     - Refresh is not enough?
//

//
// Documentation Todo:
// * Set/GetPropertyValue: Strings work for all value types.
// * SetPropertyAttribute.
// * Having graphics glitches? Use Freeze and Thaw - they have extended functionaly in PG.
//

// -----------------------------------------------------------------------

const wxChar *wxPropertyGridNameStr = wxT("wxPropertyGrid");

const wxChar *wxPGTypeName_long = wxT("long");
const wxChar *wxPGTypeName_bool = wxT("bool");
const wxChar *wxPGTypeName_double = wxT("double");
const wxChar *wxPGTypeName_wxString = wxT("string");
const wxChar *wxPGTypeName_void = wxT("void*");
const wxChar *wxPGTypeName_wxArrayString = wxT("arrstring");

#ifdef __WXPYTHON__
const wxChar *wxPGTypeName_PyObject = wxT("PyObject");
#endif

// -----------------------------------------------------------------------

static void wxPGDrawFocusRect( wxDC& dc, const wxRect& rect )
{
#if defined(__WXMSW__) && !defined(__WXWINCE__)
    /*
    RECT mswRect;
    mswRect.left = rect.x;
    mswRect.top = rect.y;
    mswRect.right = rect.x + rect.width;
    mswRect.bottom = rect.y + rect.height;
    HDC hdc = (HDC) dc.GetHDC();
    SetMapMode(hdc,MM_TEXT); // Just in case...
    DrawFocusRect(hdc,&mswRect);
    */
    // FIXME: Use DrawFocusRect code above (currently it draws solid line
    //   for caption focus but works ok for other stuff).
    //   Also, it seems that this code may not work in future wx versions.
    dc.SetLogicalFunction(wxINVERT);

    wxPen pen(*wxBLACK,1,wxDOT);
    pen.SetCap(wxCAP_BUTT);
    dc.SetPen(pen);
    dc.SetBrush(*wxTRANSPARENT_BRUSH);

    dc.DrawRectangle(rect);

    dc.SetLogicalFunction(wxCOPY);
#else
    dc.SetLogicalFunction(wxINVERT);

    dc.SetPen(wxPen(*wxBLACK,1,wxDOT));
    dc.SetBrush(*wxTRANSPARENT_BRUSH);

    dc.DrawRectangle(rect);

    dc.SetLogicalFunction(wxCOPY);
#endif
}


// -----------------------------------------------------------------------
// Choice related methods from various classes
// -----------------------------------------------------------------------

void wxPropertyContainerMethods::AddPropertyChoice( wxPGId id,
                                                    const wxString& label,
                                                    int value )
{
    wxPG_PROP_ID_CALL_PROLOG()

    p->InsertChoice(label,-1,value);
}


void wxPropertyContainerMethods::InsertPropertyChoice( wxPGId id,
                                                       const wxString& label,
                                                       int index,
                                                       int value )
{
    wxPG_PROP_ID_CALL_PROLOG()

    p->InsertChoice(label,index,value);
}


void wxPropertyContainerMethods::DeletePropertyChoice( wxPGId id,
                                                       int index )
{
    wxPG_PROP_ID_CALL_PROLOG()

    p->DeleteChoice(index);
}


// -----------------------------------------------------------------------
// Statics in one class for easy destruction.
// NB: We prefer to use wxModule, as it offers more consistent behaviour
//     across platforms. However, for those rare problem situations, we
//     also need to offer option to use simpler approach.
// -----------------------------------------------------------------------

#ifndef wxPG_USE_WXMODULE
    #define wxPG_USE_WXMODULE 1
#endif

#if wxPG_USE_WXMODULE

#include <wx/module.h>

class wxPGGlobalVarsClassManager : public wxModule
{
    DECLARE_DYNAMIC_CLASS(wxPGGlobalVarsClassManager)
public:
    wxPGGlobalVarsClassManager() {}
    virtual bool OnInit() { wxPGGlobalVars = new wxPGGlobalVarsClass(); return true; }
    virtual void OnExit() { delete wxPGGlobalVars; wxPGGlobalVars = NULL; }
};

IMPLEMENT_DYNAMIC_CLASS(wxPGGlobalVarsClassManager, wxModule)

#else // !wxPG_USE_WXMODULE

class wxPGGlobalVarsClassManager
{
public:
    wxPGGlobalVarsClassManager() {}
    ~wxPGGlobalVarsClassManager() { delete wxPGGlobalVars; }
};

static wxPGGlobalVarsClassManager gs_pgGlobalVarsClassManager;

#endif


wxPGGlobalVarsClass* wxPGGlobalVars = (wxPGGlobalVarsClass*) NULL;


wxPGGlobalVarsClass::wxPGGlobalVarsClass()
{
    m_boolChoices[0] = _("False");
    m_boolChoices[1] = _("True");
    m_boolChoices[2] = _("Unspecified");
    m_numBoolChoices = 2;

    m_fontFamilyChoices = (wxPGChoices*) NULL;

    m_autoGetTranslation = false;

    m_offline = 0;
}


wxPGGlobalVarsClass::~wxPGGlobalVarsClass()
{
    size_t i;

    // This will always have one ref
    delete m_fontFamilyChoices;

#if wxUSE_VALIDATORS
    for ( i=0; i<m_arrValidators.GetCount(); i++ )
        delete ((wxValidator*)m_arrValidators[i]);
#endif

    //
    // Destroy value type class instances.
    wxPGHashMapS2P::iterator vt_it;

    for( vt_it = m_dictValueType.begin(); vt_it != m_dictValueType.end(); ++vt_it )
    {
        wxPGValueType* pcls = (wxPGValueType*) vt_it->second;
        wxASSERT( pcls );
        delete pcls;
    }

    // Destroy editor class instances.
    // iterate over all the elements in the class
    for( vt_it = m_mapEditorClasses.begin(); vt_it != m_mapEditorClasses.end(); ++vt_it )
    {
        delete ((wxPGEditor*)vt_it->second);
    }
}

// -----------------------------------------------------------------------
// wxPGProperty
// -----------------------------------------------------------------------

wxPGPropertyClassInfo wxBasePropertyClassInfo = {wxT("wxBaseProperty"),
                                                 (const wxPGPropertyClassInfo*) NULL,
                                                 (wxPGPropertyConstructor) NULL};

void wxPGProperty::Init()
{
#ifdef __WXPYTHON__
    m_scriptObject = NULL;
#endif

    m_y = -3;
    m_arrIndex = 0xFFFF;
    m_parent = (wxPGPropertyWithChildren*) NULL;

#if wxPG_USE_CLIENT_DATA
    m_clientData = (void*) NULL;
#endif

    m_dataExt = (wxPGPropertyDataExt*) NULL;

    m_maxLen = 0; // infinite maximum length

    m_flags = 0;

    m_depth = 1;
    m_parentingType = 0;
    m_bgColIndex = 0;
    m_fgColIndex = 0;
}


void wxPGProperty::Init( const wxString& label, const wxString& name )
{
    m_label = label;
#ifndef __WXPYTHON__
    if ( &name != ((wxString*)NULL) )
#else
    if ( (&name != ((wxString*)NULL)) && name != wxT("_LABEL_AS_NAME") )
#endif
        DoSetName( name );
    else
        DoSetName( label );

    Init();
}

wxPGProperty::wxPGProperty()
#if wxPG_INCLUDE_WXOBJECT
    : wxObject()
#endif
{
    Init();
}


wxPGProperty::wxPGProperty( const wxString& label, const wxString& name )
#if wxPG_INCLUDE_WXOBJECT
    : wxObject()
#endif
{
    Init( label, name );
}


wxPGProperty::~wxPGProperty()
{
    delete m_dataExt;
}


bool wxPGProperty::IsSomeParent( wxPGProperty* candidate ) const
{
    wxPGPropertyWithChildren* parent = m_parent;
    do
    {
        if ( parent == (wxPGPropertyWithChildren*)candidate )
            return true;
        parent = parent->m_parent;
    } while ( parent );
    return false;
}


wxPropertyGridState* wxPGProperty::GetParentState() const
{
    wxASSERT( m_parent );

⌨️ 快捷键说明

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