preserve custom colours between calls to wxGetColourFromUser(), also allow passing a custom wxColourData to it (modified patch 1832582)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50056 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-11-18 19:33:34 +00:00
parent 2349ba4cf9
commit e6ef9ea4ed
7 changed files with 162 additions and 32 deletions

View File

@@ -2109,7 +2109,7 @@ customization.
\membersection{::wxGetColourFromUser}\label{wxgetcolourfromuser}
\func{wxColour}{wxGetColourFromUser}{\param{wxWindow *}{parent}, \param{const wxColour\& }{colInit}, \param{const wxString\& }{caption = wxEmptyString}}
\func{wxColour}{wxGetColourFromUser}{\param{wxWindow *}{parent}, \param{const wxColour\& }{colInit}, \param{const wxString\& }{caption = wxEmptyString}, \param{wxColourData *}{data = \NULL}}
Shows the colour selection dialog and returns the colour selected by user or
invalid colour (use \helpref{wxColour:IsOk}{wxcolourisok} to test whether a colour
@@ -2123,6 +2123,10 @@ is valid) if the dialog was cancelled.
\docparam{caption}{If given, this will be used for the dialog caption.}
\docparam{data}{Optional object storing additional colour dialog settings, such
as custom colours. If none is provided the same settings as the last time are
used.}
\wxheading{Include files}
<wx/colordlg.h>

View File

@@ -29,8 +29,15 @@ class WXDLLIMPEXP_FWD_CORE wxPrintNativeDataBase;
class WXDLLEXPORT wxColourData : public wxObject
{
public:
// number of custom colours we store
enum
{
NUM_CUSTOM = 16
};
wxColourData();
wxColourData(const wxColourData& data);
void operator=(const wxColourData&);
virtual ~wxColourData();
void SetChooseFull(bool flag) { m_chooseFull = flag; }
@@ -39,15 +46,18 @@ public:
const wxColour& GetColour() const { return m_dataColour; }
wxColour& GetColour() { return m_dataColour; }
// Array of 16 custom colours
// These functions modify colours in an internal array of NUM_CUSTOM custom
// colours
void SetCustomColour(int i, const wxColour& colour);
wxColour GetCustomColour(int i);
void operator=(const wxColourData& data);
// Serialize the object to a string and restore it from it
wxString ToString() const;
bool FromString(const wxString& str);
public:
public: // TODO: make these fields private
wxColour m_dataColour;
wxColour m_custColours[16];
wxColour m_custColours[NUM_CUSTOM];
bool m_chooseFull;
private:

View File

@@ -30,10 +30,14 @@
#define wxColourDialog wxGenericColourDialog
#endif
class WXDLLIMPEXP_FWD_CORE wxColourData;
// get the colour from user and return it
wxColour WXDLLEXPORT
wxGetColourFromUser(wxWindow *parent = (wxWindow *)NULL,
const wxColour& colInit = wxNullColour, const wxString& caption = wxEmptyString);
const wxColour& colInit = wxNullColour,
const wxString& caption = wxEmptyString,
wxColourData *data = NULL);
#endif // wxUSE_COLOURDLG

View File

@@ -119,6 +119,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
#if wxUSE_COLOURDLG
EVT_MENU(DIALOGS_CHOOSE_COLOUR, MyFrame::ChooseColour)
EVT_MENU(DIALOGS_GET_COLOUR, MyFrame::GetColour)
#endif // wxUSE_COLOURDLG
#if wxUSE_FONTDLG
@@ -271,7 +272,8 @@ bool MyApp::OnInit()
wxMenu *choices_menu = new wxMenu;
#if wxUSE_COLOURDLG
choices_menu->Append(DIALOGS_CHOOSE_COLOUR, _T("&Choose colour"));
choices_menu->Append(DIALOGS_CHOOSE_COLOUR, _T("&Choose bg colour"));
choices_menu->Append(DIALOGS_GET_COLOUR, _T("&Choose fg colour"));
#endif // wxUSE_COLOURDLG
#if wxUSE_FONTDLG
@@ -463,16 +465,10 @@ MyFrame::MyFrame(wxWindow *parent,
#if wxUSE_COLOURDLG
m_clrData.SetChooseFull(true);
for (int i = 0; i < 16; i++)
for (int i = 0; i < wxColourData::NUM_CUSTOM; i++)
{
m_clrData.SetCustomColour(
i,
wxColour(
(unsigned char)(i*16),
(unsigned char)(i*16),
(unsigned char)(i*16)
)
);
unsigned char n = i*16;
m_clrData.SetCustomColour(i, wxColour(n, n, n));
}
#endif // wxUSE_COLOURDLG
@@ -482,12 +478,13 @@ MyFrame::MyFrame(wxWindow *parent,
}
#if wxUSE_COLOURDLG
void MyFrame::ChooseColour(wxCommandEvent& WXUNUSED(event))
{
m_clrData.SetColour(myCanvas->GetBackgroundColour());
wxColourDialog dialog(this, &m_clrData);
dialog.SetTitle(_T("Choose the background colour"));
dialog.SetTitle(_("Please choose the background colour"));
if ( dialog.ShowModal() == wxID_OK )
{
m_clrData = dialog.GetColourData();
@@ -496,8 +493,26 @@ void MyFrame::ChooseColour(wxCommandEvent& WXUNUSED(event) )
myCanvas->Refresh();
}
}
void MyFrame::GetColour(wxCommandEvent& WXUNUSED(event))
{
wxColour clr = wxGetColourFromUser
(
this,
wxGetApp().m_canvasTextColour,
"Please choose the foreground colour"
);
if ( clr.IsOk() )
{
wxGetApp().m_canvasTextColour = clr;
myCanvas->Refresh();
}
//else: dialog cancelled by user
}
#endif // wxUSE_COLOURDLG
#if USE_COLOURDLG_GENERIC
void MyFrame::ChooseColourGeneric(wxCommandEvent& WXUNUSED(event))
{

View File

@@ -211,6 +211,7 @@ public:
#if wxUSE_COLOURDLG
void ChooseColour(wxCommandEvent& event);
void GetColour(wxCommandEvent& event);
#endif // wxUSE_COLOURDLG
#if wxUSE_FONTDLG
@@ -341,6 +342,7 @@ public:
enum
{
DIALOGS_CHOOSE_COLOUR = wxID_HIGHEST,
DIALOGS_GET_COLOUR,
DIALOGS_CHOOSE_COLOUR_GENERIC,
DIALOGS_CHOOSE_FONT,
DIALOGS_CHOOSE_FONT_GENERIC,

View File

@@ -89,14 +89,14 @@ wxColourData::~wxColourData()
void wxColourData::SetCustomColour(int i, const wxColour& colour)
{
wxCHECK_RET( (i >= 0 && i < 16), _T("custom colour index out of range") );
wxCHECK_RET( (i >= 0 && i < WXSIZEOF(m_custColours)), _T("custom colour index out of range") );
m_custColours[i] = colour;
}
wxColour wxColourData::GetCustomColour(int i)
{
wxCHECK_MSG( (i >= 0 && i < 16), wxColour(0,0,0),
wxCHECK_MSG( (i >= 0 && i < WXSIZEOF(m_custColours)), wxColour(0,0,0),
_T("custom colour index out of range") );
return m_custColours[i];
@@ -104,14 +104,77 @@ wxColour wxColourData::GetCustomColour(int i)
void wxColourData::operator=(const wxColourData& data)
{
int i;
for (i = 0; i < 16; i++)
for (int i = 0; i < WXSIZEOF(m_custColours); i++)
m_custColours[i] = data.m_custColours[i];
m_dataColour = (wxColour&)data.m_dataColour;
m_dataColour = data.m_dataColour;
m_chooseFull = data.m_chooseFull;
}
// ----------------------------------------------------------------------------
// [de]serialization
// ----------------------------------------------------------------------------
// separator used between different fields
static const char wxCOL_DATA_SEP = ',';
wxString wxColourData::ToString() const
{
wxString str(m_chooseFull ? '1' : '0');
for ( int i = 0; i < WXSIZEOF(m_custColours); i++ )
{
str += wxCOL_DATA_SEP;
const wxColour& clr = m_custColours[i];
if ( clr.IsOk() )
str += clr.GetAsString(wxC2S_HTML_SYNTAX);
}
return str;
}
bool wxColourData::FromString(const wxString& str)
{
wxString token;
int n = -1; // index of the field, -1 corresponds to m_chooseFull
for ( wxString::const_iterator i = str.begin(); i != str.end(); ++i )
{
if ( *i == wxCOL_DATA_SEP )
{
if ( n == -1 )
{
if ( token == '0' )
m_chooseFull = false;
else if ( token == '1' )
m_chooseFull = true;
else // only '0' and '1' are used in ToString()
return false;
}
else // custom colour
{
if ( n == WXSIZEOF(m_custColours) )
return false; // too many custom colours
// empty strings are used by ToString() for colours not used
if ( token.empty() )
m_custColours[n] = wxNullColour;
else if ( !m_custColours[n].Set(token) )
return false; // invalid colour string
}
token.clear();
n++;
}
else // continuation of the current field
{
token += *i;
}
}
return true;
}
// ----------------------------------------------------------------------------
// Font data
// ----------------------------------------------------------------------------

View File

@@ -1419,24 +1419,56 @@ wxString wxGetPasswordFromUser(const wxString& message,
#if wxUSE_COLOURDLG
wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit, const wxString& caption)
wxColour wxGetColourFromUser(wxWindow *parent,
const wxColour& colInit,
const wxString& caption,
wxColourData *ptrData)
{
// contains serialized representation of wxColourData used the last time
// the dialog was shown: we want to reuse it the next time in order to show
// the same custom colours to the user (and we can't just have static
// wxColourData itself because it's a GUI object and so should be destroyed
// before GUI shutdown and doing it during static cleanup is too late)
static wxString s_strColourData;
wxColourData data;
data.SetChooseFull(true);
if ( colInit.Ok() )
if ( !ptrData )
{
data.SetColour((wxColour &)colInit); // const_cast
ptrData = &data;
if ( !s_strColourData.empty() )
{
if ( !data.FromString(s_strColourData) )
{
wxFAIL_MSG( "bug in wxColourData::FromString()?" );
}
#ifdef __WXMSW__
// we don't get back the "choose full" flag value from the native
// dialog and so we can't preserve it between runs, so we decide to
// always use it as it seems better than not using it (user can
// just ignore the extra controls in the dialog but having to click
// a button each time to show them would be very annoying
data.SetChooseFull(true);
#endif // __WXMSW__
}
}
if ( colInit.IsOk() )
{
ptrData->SetColour(colInit);
}
wxColour colRet;
wxColourDialog dialog(parent, &data);
wxColourDialog dialog(parent, ptrData);
if (!caption.empty())
dialog.SetTitle(caption);
if ( dialog.ShowModal() == wxID_OK )
{
colRet = dialog.GetColourData().GetColour();
*ptrData = dialog.GetColourData();
colRet = ptrData->GetColour();
s_strColourData = ptrData->ToString();
}
//else: leave it invalid
//else: leave colRet invalid
return colRet;
}