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} \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 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 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{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} \wxheading{Include files}
<wx/colordlg.h> <wx/colordlg.h>

View File

@@ -26,11 +26,18 @@
class WXDLLIMPEXP_FWD_CORE wxPrintNativeDataBase; class WXDLLIMPEXP_FWD_CORE wxPrintNativeDataBase;
class WXDLLEXPORT wxColourData: public wxObject class WXDLLEXPORT wxColourData : public wxObject
{ {
public: public:
// number of custom colours we store
enum
{
NUM_CUSTOM = 16
};
wxColourData(); wxColourData();
wxColourData(const wxColourData& data); wxColourData(const wxColourData& data);
void operator=(const wxColourData&);
virtual ~wxColourData(); virtual ~wxColourData();
void SetChooseFull(bool flag) { m_chooseFull = flag; } void SetChooseFull(bool flag) { m_chooseFull = flag; }
@@ -39,15 +46,18 @@ public:
const wxColour& GetColour() const { return m_dataColour; } const wxColour& GetColour() const { return m_dataColour; }
wxColour& GetColour() { 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); void SetCustomColour(int i, const wxColour& colour);
wxColour GetCustomColour(int i); 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_dataColour;
wxColour m_custColours[16]; wxColour m_custColours[NUM_CUSTOM];
bool m_chooseFull; bool m_chooseFull;
private: private:

View File

@@ -30,10 +30,14 @@
#define wxColourDialog wxGenericColourDialog #define wxColourDialog wxGenericColourDialog
#endif #endif
class WXDLLIMPEXP_FWD_CORE wxColourData;
// get the colour from user and return it // get the colour from user and return it
wxColour WXDLLEXPORT wxColour WXDLLEXPORT
wxGetColourFromUser(wxWindow *parent = (wxWindow *)NULL, 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 #endif // wxUSE_COLOURDLG

View File

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

View File

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

View File

@@ -89,14 +89,14 @@ wxColourData::~wxColourData()
void wxColourData::SetCustomColour(int i, const wxColour& colour) 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; m_custColours[i] = colour;
} }
wxColour wxColourData::GetCustomColour(int i) 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") ); _T("custom colour index out of range") );
return m_custColours[i]; return m_custColours[i];
@@ -104,14 +104,77 @@ wxColour wxColourData::GetCustomColour(int i)
void wxColourData::operator=(const wxColourData& data) void wxColourData::operator=(const wxColourData& data)
{ {
int i; for (int i = 0; i < WXSIZEOF(m_custColours); i++)
for (i = 0; i < 16; i++)
m_custColours[i] = data.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; 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 // Font data
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -1419,24 +1419,56 @@ wxString wxGetPasswordFromUser(const wxString& message,
#if wxUSE_COLOURDLG #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; wxColourData data;
data.SetChooseFull(true); if ( !ptrData )
if ( colInit.Ok() )
{ {
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; wxColour colRet;
wxColourDialog dialog(parent, &data); wxColourDialog dialog(parent, ptrData);
if (!caption.empty()) if (!caption.empty())
dialog.SetTitle(caption); dialog.SetTitle(caption);
if ( dialog.ShowModal() == wxID_OK ) 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; return colRet;
} }