📄 advprops.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: advprops.cpp
// Purpose: wxPropertyGrid Advanced Properties (font, colour, etc.)
// Author: Jaakko Salli
// Modified by:
// Created: Sep-25-2004
// RCS-ID: $Id:
// Copyright: (c) Jaakko Salli
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "advprops.h"#endif
// For compilers that support precompilation, includes "wx/wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__ #pragma hdrstop#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/object.h"
#include "wx/hash.h"
#include "wx/string.h"
#include "wx/log.h"
#include "wx/event.h"
#include "wx/window.h"
#include "wx/panel.h"
#include "wx/dc.h"
#include "wx/dcclient.h"
#include "wx/button.h"
#include "wx/pen.h"
#include "wx/brush.h"
#include "wx/cursor.h"
#include "wx/dialog.h"
#include "wx/settings.h"
#include "wx/msgdlg.h"
#include "wx/choice.h"
#include "wx/stattext.h"
#include "wx/textctrl.h"
#include "wx/scrolwin.h"
#include "wx/dirdlg.h"
#include "wx/combobox.h"
#include "wx/layout.h"
#include "wx/sizer.h"
#include "wx/textdlg.h"
#include "wx/filedlg.h"
#include "wx/intl.h"
#endif
#define __wxPG_SOURCE_FILE__
#include <wx/propgrid/propgrid.h>
#if wxPG_INCLUDE_ADVPROPS
#include <wx/propgrid/propdev.h>
#include <wx/propgrid/advprops.h>
#ifdef __WXMSW__
#include <wx/msw/private.h>
#endif
// -----------------------------------------------------------------------
#if defined(__WXMSW__)
#define wxPG_CAN_DRAW_CURSOR 1
#elif defined(__WXGTK__)
#define wxPG_CAN_DRAW_CURSOR 0
#elif defined(__WXMAC__)
#define wxPG_CAN_DRAW_CURSOR 0
#else
#define wxPG_CAN_DRAW_CURSOR 0
#endif
#if !defined(wxPG_ALLOW_WXADV)
#undef wxUSE_DATEPICKCTRL
#define wxUSE_DATEPICKCTRL 0
#endif
// -----------------------------------------------------------------------
// Value type related
// -----------------------------------------------------------------------
bool operator == (const wxFont&, const wxFont&)
{
return false;
}
WX_PG_IMPLEMENT_VALUE_TYPE_WXOBJ(wxFont,wxFontProperty,(const wxFont*)NULL)
// Implement dynamic class for type value.
IMPLEMENT_DYNAMIC_CLASS(wxColourPropertyValue,wxObject)
bool operator == (const wxColourPropertyValue& a, const wxColourPropertyValue& b)
{
return ( ( a.m_colour == b.m_colour ) && (a.m_type == b.m_type) );
}
WX_PG_IMPLEMENT_VALUE_TYPE_WXOBJ(wxColourPropertyValue,wxSystemColourProperty,
(const wxColourPropertyValue*)NULL)
WX_PG_IMPLEMENT_VALUE_TYPE_WXOBJ(wxColour,wxColourProperty,
(const wxColour*)wxBLACK)
bool operator == (const wxArrayInt& array1, const wxArrayInt& array2)
{
if ( array1.GetCount() != array2.GetCount() )
return false;
size_t i;
for ( i=0; i<array1.GetCount(); i++ )
{
if ( array1[i] != array2[i] )
return false;
}
return true;
}
WX_PG_IMPLEMENT_VALUE_TYPE_VOIDP(wxArrayInt,
wxMultiChoiceProperty,
wxArrayInt())
#if wxUSE_DATETIME
// This macro can be used for values that have built-in support in wxVariant.
WX_PG_IMPLEMENT_VALUE_TYPE(wxDateTime,wxDateProperty,wxT("datetime"),GetDateTime,wxDateTime())
#endif
// -----------------------------------------------------------------------
// wxSpinCtrl-based property editor
// -----------------------------------------------------------------------
#if wxUSE_SPINBTN
//
// Implement an editor control that allows using wxSpinCtrl (actually,
// a combination of wxTextCtrl and wxSpinButton) to edit value of
// wxIntProperty and wxFloatProperty (and similar).
//
// Note that new editor classes needs to be registered before use.
// This can be accomplished using wxPGRegisterEditorClass macro, which
// is used for SpinCtrl in wxPropertyContainerMethods::RegisterAdditionalEditors
// (see below). Registeration can also be performed in a constructor of a
// property that is likely to require the editor in question.
//
#include <wx/spinbutt.h>
// NOTE: Regardless that this class inherits from a working editor, it has
// all necessary methods to work independently. wxTextCtrl stuff is only
// used for event handling here.
class wxPGSpinCtrlEditor : public wxPGTextCtrlEditor
{
WX_PG_DECLARE_EDITOR_CLASS()
public:
virtual ~wxPGSpinCtrlEditor();
// See below for short explanations of what these are suppposed to do.
wxPG_DECLARE_CREATECONTROLS
virtual bool OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
wxWindow* wnd, wxEvent& event ) const;
};
// This macro also defines global wxPGEditor_SpinCtrl for storing
// the singleton class instance.
WX_PG_IMPLEMENT_EDITOR_CLASS(SpinCtrl,wxPGSpinCtrlEditor,wxPGEditor)
// Trivial destructor.
wxPGSpinCtrlEditor::~wxPGSpinCtrlEditor()
{
}
// Create controls and initialize event handling.
#ifndef __WXPYTHON__
wxWindow* wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property,
const wxPoint& pos, const wxSize& sz, wxWindow** pSecondary ) const
#else
wxPGWindowPair wxPGSpinCtrlEditor::CreateControls( wxPropertyGrid* propgrid, wxPGProperty* property,
const wxPoint& pos, const wxSize& sz ) const
#endif
{
const int margin = 1;
wxSize butSz(18, sz.y);
wxSize tcSz(sz.x - butSz.x - margin, sz.y);
wxPoint butPos(pos.x + tcSz.x + margin, pos.y);
wxSpinButton* wnd2 = new wxSpinButton();
#ifdef __WXMSW__
wnd2->Hide();
#endif
wnd2->Create( propgrid, wxPG_SUBID2, butPos, butSz, wxSP_VERTICAL );
wnd2->SetRange( INT_MIN, INT_MAX );
//wnd2->SetRange( 5, 12 );
wnd2->SetValue( 0 );
propgrid->Connect( wxPG_SUBID2, wxEVT_SCROLL_LINEUP,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
&wxPropertyGrid::OnCustomEditorEvent, NULL, propgrid );
propgrid->Connect( wxPG_SUBID2, wxEVT_SCROLL_LINEDOWN,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
&wxPropertyGrid::OnCustomEditorEvent, NULL, propgrid );
// Let's add validator to make sure only numbers can be entered
wxString temps;
wxTextValidator validator(wxFILTER_NUMERIC, &temps);
#ifndef __WXPYTHON__
wxTextCtrl* wnd1 = (wxTextCtrl*) wxPGTextCtrlEditor::CreateControls( propgrid, property, pos, tcSz, NULL );
wnd1->SetValidator(validator);
*pSecondary = wnd2;
return wnd1;
#else
wxTextCtrl* wnd1 = (wxTextCtrl*) wxPGTextCtrlEditor::CreateControls( propgrid, property, pos, tcSz ).m_primary;
wnd1->SetValidator(validator);
return wxPGWindowPair(wnd1, wnd2);
#endif
}
// Control's events are redirected here
bool wxPGSpinCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
wxWindow* wnd, wxEvent& event ) const
{
int evtType = event.GetEventType();
if ( evtType == wxEVT_SCROLL_LINEUP || evtType == wxEVT_SCROLL_LINEDOWN )
{
wxString s;
// Can't use wnd since it might be clipper window
wxTextCtrl* tc = wxDynamicCast(propgrid->GetEditorControl(), wxTextCtrl);
if ( tc )
s = tc->GetValue();
else
s = property->GetValueAsString(wxPG_FULL_VALUE);
wxSpinButton* spinButton = (wxSpinButton*) propgrid->GetEditorControlSecondary();
int spinMin = spinButton->GetMin();
int spinMax = spinButton->GetMax();
if ( property->GetValueType() == wxPG_VALUETYPE(double) )
{
double v_d;
// Try double
if ( s.ToDouble(&v_d) )
{
if ( evtType == wxEVT_SCROLL_LINEUP ) v_d += 1.0;
else v_d -= 1.0;
// Min/Max
double dSpinMin = (double) spinMin;
double dSpinMax = (double) spinMax;
if ( v_d > dSpinMax ) v_d = dSpinMax;
else if ( v_d < dSpinMin ) v_d = dSpinMin;
wxPropertyGrid::DoubleToString(s, v_d, 6, true, NULL);
}
else
{
return false;
}
}
else
{
long v_l;
// Try long
if ( s.ToLong(&v_l, 0) )
{
if ( evtType == wxEVT_SCROLL_LINEUP ) v_l++;
else v_l--;
// Min/Max
if ( v_l > spinMax ) v_l = spinMax;
else if ( v_l < spinMin ) v_l = spinMin;
s = wxString::Format(wxT("%i"),(int)v_l);
}
else
{
return false;
}
}
if ( tc )
tc->SetValue(s);
return true;
}
return wxPGTextCtrlEditor::OnEvent(propgrid,property,wnd,event);
}
#endif // wxUSE_SPINBTN
// -----------------------------------------------------------------------
// wxDatePickerCtrl-based property editor
// -----------------------------------------------------------------------
#if wxUSE_DATEPICKCTRL
#include <wx/datectrl.h>
#include <wx/dateevt.h>
class wxPGDatePickerCtrlEditor : public wxPGEditor
{
WX_PG_DECLARE_EDITOR_CLASS()
public:
virtual ~wxPGDatePickerCtrlEditor();
wxPG_DECLARE_CREATECONTROLS
virtual void UpdateControl( wxPGProperty* property, wxWindow* wnd ) const;
virtual bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid* propgrid, wxPGProperty* property,
wxWindow* wnd, wxEvent& event ) const;
virtual bool CopyValueFromControl( wxPGProperty* property, wxWindow* wnd ) const;
virtual void SetValueToUnspecified( wxWindow* wnd ) const;
};
WX_PG_IMPLEMENT_EDITOR_CLASS(DatePickerCtrl,wxPGDatePickerCtrlEditor,wxPGEditor)
wxPGDatePickerCtrlEditor::~wxPGDatePickerCtrlEditor()
{
}
#ifndef __WXPYTHON__
wxWindow* wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid* propgrid,
wxPGProperty* property,
const wxPoint& pos,
const wxSize& sz,
wxWindow** ) const
#else
wxPGWindowPair wxPGDatePickerCtrlEditor::CreateControls( wxPropertyGrid* propgrid,
wxPGProperty* property,
const wxPoint& pos,
const wxSize& sz ) const
#endif
{
wxCHECK_MSG( property->IsKindOf(WX_PG_CLASSINFO(wxDateProperty)),
NULL,
wxT("DatePickerCtrl editor can only be used with wxDateProperty or derivative.") );
wxDatePropertyClass* prop = (wxDatePropertyClass*) property;
// Use two stage creation to allow cleaner display on wxMSW
wxDatePickerCtrl* ctrl = new wxDatePickerCtrl();
#ifdef __WXMSW__
ctrl->Hide();
wxSize useSz = wxDefaultSize;
useSz.x = sz.x;
#else
wxSize useSz = sz;
#endif
ctrl->Create(propgrid,
wxPG_SUBID1,
prop->GetDateValue(),
pos,
useSz,
prop->GetDatePickerStyle() | wxNO_BORDER);
// Connect all required events to grid's OnCustomEditorEvent
// (all relevenat wxTextCtrl, wxComboBox and wxButton events are
// already connected)
propgrid->Connect( wxPG_SUBID1, wxEVT_DATE_CHANGED,
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
&wxPropertyGrid::OnCustomEditorEvent );
#ifdef __WXMSW__
ctrl->Show();
#endif
return ctrl;
}
// Copies value from property to control
void wxPGDatePickerCtrlEditor::UpdateControl( wxPGProperty* property, wxWindow* wnd ) const
{
wxDatePickerCtrl* ctrl = (wxDatePickerCtrl*) wnd;
wxASSERT( ctrl && ctrl->IsKindOf(CLASSINFO(wxDatePickerCtrl)) );
// We assume that property's data type is 'int' (or something similar),
// thus allowing us to get raw, unchecked value via DoGetValue.
ctrl->SetValue( *((const wxDateTime*)property->DoGetValue().GetVoidPtr()) );
}
// Control's events are redirected here
bool wxPGDatePickerCtrlEditor::OnEvent( wxPropertyGrid* WXUNUSED(propgrid),
wxPGProperty* WXUNUSED(property),
wxWindow* WXUNUSED(wnd),
wxEvent& event ) const
{
if ( event.GetEventType() == wxEVT_DATE_CHANGED )
return true;
return false;
}
bool wxPGDatePickerCtrlEditor::CopyValueFromControl( wxPGProperty* property, wxWindow* wnd ) const
{
wxDatePickerCtrl* ctrl = (wxDatePickerCtrl*) wnd;
wxASSERT( ctrl && ctrl->IsKindOf(CLASSINFO(wxDatePickerCtrl)) );
wxDatePropertyClass* prop = (wxDatePropertyClass*) property;
prop->SetDateValue( ctrl->GetValue() );
return true;
}
void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxWindow* WXUNUSED(wnd) ) const
{
// TODO?
//wxDateProperty* prop = (wxDateProperty*) property;
//ctrl->SetValue(?);
}
#endif // wxUSE_DATEPICKCTRL
// -----------------------------------------------------------------------
// wxFontProperty
// -----------------------------------------------------------------------
#include <wx/fontdlg.h>
#include <wx/fontenum.h>
static const wxChar* gs_fp_es_family_labels[] = {
wxT("Default"), wxT("Decorative"),
wxT("Roman"), wxT("Script"),
wxT("Swiss"), wxT("Modern"),
(const wxChar*) NULL
};
static long gs_fp_es_family_values[] = {
wxDEFAULT, wxDECORATIVE,
wxROMAN, wxSCRIPT,
wxSWISS, wxMODERN
};
static const wxChar* gs_fp_es_style_labels[] = {
wxT("Normal"),
wxT("Slant"),
wxT("Italic"),
(const wxChar*) NULL
};
static long gs_fp_es_style_values[] = {
wxNORMAL,
wxSLANT,
wxITALIC
};
static const wxChar* gs_fp_es_weight_labels[] = {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -