\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
\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>
class WXDLLIMPEXP_FWD_CORE wxPrintNativeDataBase;
-class WXDLLEXPORT wxColourData: public wxObject
+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; }
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:
#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
#if wxUSE_COLOURDLG
EVT_MENU(DIALOGS_CHOOSE_COLOUR, MyFrame::ChooseColour)
+ EVT_MENU(DIALOGS_GET_COLOUR, MyFrame::GetColour)
#endif // wxUSE_COLOURDLG
#if wxUSE_FONTDLG
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
#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
}
#if wxUSE_COLOURDLG
-void MyFrame::ChooseColour(wxCommandEvent& WXUNUSED(event) )
+
+void MyFrame::ChooseColour(wxCommandEvent& WXUNUSED(event))
{
m_clrData.SetColour(myCanvas->GetBackgroundColour());
wxColourDialog dialog(this, &m_clrData);
- dialog.SetTitle(_T("Choose the background colour"));
- if (dialog.ShowModal() == wxID_OK)
+ dialog.SetTitle(_("Please choose the background colour"));
+ if ( dialog.ShowModal() == wxID_OK )
{
m_clrData = dialog.GetColourData();
myCanvas->SetBackgroundColour(m_clrData.GetColour());
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))
{
#if wxUSE_COLOURDLG
void ChooseColour(wxCommandEvent& event);
+ void GetColour(wxCommandEvent& event);
#endif // wxUSE_COLOURDLG
#if wxUSE_FONTDLG
enum
{
DIALOGS_CHOOSE_COLOUR = wxID_HIGHEST,
+ DIALOGS_GET_COLOUR,
DIALOGS_CHOOSE_COLOUR_GENERIC,
DIALOGS_CHOOSE_FONT,
DIALOGS_CHOOSE_FONT_GENERIC,
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];
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
// ----------------------------------------------------------------------------
#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;
}