1. wxSingleChoiceDialog looks Ok under Windows

2. wxDialog now longer is resizeable by default
3. wxProgressDialog has a more reasonable width


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2896 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-06-25 21:28:25 +00:00
parent 8736a9a0d3
commit 257bf51016
4 changed files with 296 additions and 159 deletions

View File

@@ -22,38 +22,70 @@
#define wxCHOICE_HEIGHT 150 #define wxCHOICE_HEIGHT 150
#define wxCHOICE_WIDTH 200 #define wxCHOICE_WIDTH 200
#define wxID_LISTBOX 3000 #define wxCHOICEDLG_STYLE (wxOK | wxCANCEL | wxCENTRE)
class WXDLLEXPORT wxSingleChoiceDialog: public wxDialog class WXDLLEXPORT wxSingleChoiceDialog: public wxDialog
{ {
DECLARE_DYNAMIC_CLASS(wxSingleChoiceDialog) DECLARE_DYNAMIC_CLASS(wxSingleChoiceDialog)
public: public:
wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, wxSingleChoiceDialog(wxWindow *parent,
int n, const wxString *choices, wxChar **clientData = (wxChar **) NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition); const wxString& message,
const wxString& caption,
int n,
const wxString *choices,
char **clientData = (char **)NULL,
long style = wxCHOICEDLG_STYLE,
const wxPoint& pos = wxDefaultPosition);
wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, wxSingleChoiceDialog(wxWindow *parent,
const wxStringList& choices, wxChar **clientData = (wxChar **) NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition); const wxString& message,
const wxString& caption,
const wxStringList& choices,
char **clientData = (char **)NULL,
long style = wxCHOICEDLG_STYLE,
const wxPoint& pos = wxDefaultPosition);
bool Create(wxWindow *parent, const wxString& message, const wxString& caption, bool Create(wxWindow *parent,
int n, const wxString *choices, wxChar **clientData = (wxChar **) NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition); const wxString& message,
bool Create(wxWindow *parent, const wxString& message, const wxString& caption, const wxString& caption,
const wxStringList& choices, wxChar **clientData = (wxChar **) NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition); int n,
const wxString *choices,
char **clientData = (char **)NULL,
long style = wxCHOICEDLG_STYLE,
const wxPoint& pos = wxDefaultPosition);
bool Create(wxWindow *parent,
const wxString& message,
const wxString& caption,
const wxStringList& choices,
char **clientData = (char **)NULL,
long style = wxCHOICEDLG_STYLE,
const wxPoint& pos = wxDefaultPosition);
void SetSelection(int sel) ; void SetSelection(int sel) ;
inline int GetSelection(void) const { return m_selection; } int GetSelection() const { return m_selection; }
inline wxString GetStringSelection(void) const { return m_stringSelection; } wxString GetStringSelection() const { return m_stringSelection; }
inline wxChar *GetSelectionClientData(void) const { return m_clientData; }
// get client data associated with selection
void *GetClientData() const { return m_clientData; }
// obsolete function (NB: no need to make it return wxChar, it's untyped)
char *GetSelectionClientData() const { return (char *)m_clientData; }
// implementation from now on
void OnOK(wxCommandEvent& event); void OnOK(wxCommandEvent& event);
void OnListBoxDClick(wxCommandEvent& event); void OnListBoxDClick(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
protected: protected:
long m_dialogStyle; long m_dialogStyle;
int m_selection; int m_selection;
wxString m_stringSelection; wxString m_stringSelection;
wxChar* m_clientData; void *m_clientData;
wxListBox *m_listbox;
private:
DECLARE_EVENT_TABLE()
}; };
WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, const wxString& caption, WXDLLEXPORT wxString wxGetSingleChoice(const wxString& message, const wxString& caption,
@@ -79,14 +111,15 @@ WXDLLEXPORT int wxGetSingleChoiceIndex(const wxString& message, const wxString&
int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT);
// Return client data instead // Return client data instead
// FIXME: this is horrible, using "char *" instead of "void *" belongs to the 70s!
WXDLLEXPORT wxChar* wxGetSingleChoiceData(const wxString& message, const wxString& caption, WXDLLEXPORT wxChar* wxGetSingleChoiceData(const wxString& message, const wxString& caption,
int n, const wxString *choices, wxChar **client_data, int n, const wxString *choices, char **client_data,
wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1, wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1,
bool centre = TRUE, bool centre = TRUE,
int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT);
WXDLLEXPORT wxChar* wxGetSingleChoiceData(const wxString& message, const wxString& caption, WXDLLEXPORT wxChar* wxGetSingleChoiceData(const wxString& message, const wxString& caption,
int n, wxChar *choices[], wxChar **client_data, int n, wxChar *choices[], char **client_data,
wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1, wxWindow *parent = (wxWindow *) NULL, int x = -1, int y = -1,
bool centre = TRUE, bool centre = TRUE,
int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT); int width = wxCHOICE_WIDTH, int height = wxCHOICE_HEIGHT);

View File

@@ -36,43 +36,7 @@
#include "wx/generic/choicdgg.h" #include "wx/generic/choicdgg.h"
/* Split message, using constraints to position controls */ #define wxID_LISTBOX 3000
static wxSize wxSplitMessage2( const wxString &message, wxWindow *parent )
{
int y = 10;
int w = 50;
wxString line( _T("") );
for (size_t pos = 0; pos < message.Len(); pos++)
{
if (message[pos] == _T('\n'))
{
if (!line.IsEmpty())
{
wxStaticText *s1 = new wxStaticText( parent, -1, line, wxPoint(15,y) );
wxSize size1( s1->GetSize() );
if (size1.x > w) w = size1.x;
line = _T("");
}
y += 18;
}
else
{
line += message[pos];
}
}
if (!line.IsEmpty())
{
wxStaticText *s2 = new wxStaticText( parent, -1, line, wxPoint(15,y) );
wxSize size2( s2->GetSize() );
if (size2.x > w) w = size2.x;
}
y += 18;
return wxSize(w+30,y);
}
wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n, wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n,
const wxString *choices, wxWindow *parent, const wxString *choices, wxWindow *parent,
@@ -200,22 +164,44 @@ END_EVENT_TABLE()
IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog) IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
#endif #endif
wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, #define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \
int n, const wxString *choices, wxChar **clientData, long style, const wxPoint& pos): wxDIALOG_MODAL | \
wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL|wxTAB_TRAVERSAL) wxTAB_TRAVERSAL)
wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
const wxString& message,
const wxString& caption,
int n,
const wxString *choices,
char **clientData,
long style,
const wxPoint& pos)
: wxDialog(parent, -1, caption, pos, wxDefaultSize,
wxCHOICEDLG_DIALOG_STYLE)
{ {
Create(parent, message, caption, n, choices, clientData, style); Create(parent, message, caption, n, choices, clientData, style);
} }
wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption, wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
const wxStringList& choices, wxChar **clientData, long style, const wxPoint& pos): const wxString& message,
wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL) const wxString& caption,
const wxStringList& choices,
wxChar **clientData,
long style,
const wxPoint& pos)
: wxDialog(parent, -1, caption, pos, wxDefaultSize,
wxCHOICEDLG_DIALOG_STYLE)
{ {
Create(parent, message, caption, choices, clientData, style); Create(parent, message, caption, choices, clientData, style);
} }
bool wxSingleChoiceDialog::Create(wxWindow *parent, const wxString& message, const wxString& caption, bool wxSingleChoiceDialog::Create(wxWindow *parent,
const wxStringList& choices, wxChar **clientData, long style, const wxPoint& pos) const wxString& message,
const wxString& caption,
const wxStringList& choices,
char **clientData,
long style,
const wxPoint& pos)
{ {
wxString *strings = new wxString[choices.Number()]; wxString *strings = new wxString[choices.Number()];
int i; int i;
@@ -228,120 +214,230 @@ bool wxSingleChoiceDialog::Create(wxWindow *parent, const wxString& message, con
return ans; return ans;
} }
bool wxSingleChoiceDialog::Create( wxWindow *WXUNUSED(parent), const wxString& message, bool wxSingleChoiceDialog::Create( wxWindow *WXUNUSED(parent),
const wxString& WXUNUSED(caption), int n, const wxString& message,
const wxString *choices, wxChar **clientData, long style, const wxString& WXUNUSED(caption),
int n,
const wxString *choices,
char **clientData,
long style,
const wxPoint& WXUNUSED(pos) ) const wxPoint& WXUNUSED(pos) )
{ {
m_dialogStyle = style; m_dialogStyle = style;
m_selection = 0; m_selection = 0;
m_stringSelection = _T("");
m_clientData = NULL; m_clientData = NULL;
wxBeginBusyCursor(); // dialog layout constants
static const int LAYOUT_X_MARGIN = 5;
static const int LAYOUT_Y_MARGIN = 5;
static const int MARGIN_BETWEEN_BUTTONS = 3*LAYOUT_X_MARGIN;
wxSize message_size( wxSplitMessage2( message, this ) ); // calc the message size
// ---------------------
wxButton *ok = (wxButton *) NULL; // TODO this should be factored out to a common function (also used in
wxButton *cancel = (wxButton *) NULL; // msgdlgg.cpp)
wxList m_buttons; wxClientDC dc(this);
dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
int y = message_size.y + 15; wxArrayString lines;
wxString curLine;
long height, width, heightTextMax = 0, widthTextMax = 0;
for ( const char *pc = message; ; pc++ ) {
if ( *pc == '\n' || *pc == '\0' ) {
dc.GetTextExtent(curLine, &width, &height);
if ( width > widthTextMax )
widthTextMax = width;
if ( height > heightTextMax )
heightTextMax = height;
int listbox_height = wxMin( 160, n*20 + 40); lines.Add(curLine);
if ( *pc == '\n' ) {
curLine.Empty();
}
else {
// the end of string
break;
}
}
else {
curLine += *pc;
}
}
size_t nLineCount = lines.Count();
long hTotalMsg = heightTextMax*nLineCount;
// calc the button size
// --------------------
bool hasCancel = FALSE;
// always create the OK button - the code below supposes we do have buttons
// and besides the user should have some way to close this dialog
wxASSERT_MSG( style & wxOK, _T("this dialog should have OK button") );
wxString labelOk(_("OK"));
long wButton = 0;
dc.GetTextExtent(labelOk, &width, NULL);
if ( width > wButton )
wButton = width;
wxString labelCancel;
if ( style & wxCANCEL )
{
labelCancel = _("Cancel");
dc.GetTextExtent(labelCancel, &width, NULL);
if ( width > wButton )
wButton = width;
hasCancel = TRUE;
}
if ( wButton < 75 )
wButton = 75;
else
wButton += 10;
long hButton = wButton*23/75;
long wTotalButtons = wButton;
if ( hasCancel )
{
wTotalButtons *= 2; // second button
wTotalButtons += MARGIN_BETWEEN_BUTTONS; // margin between the 2
}
// listbox and stat line
// ---------------------
// make the listbox at least as tall as the message - otherwise it looks
// ugly (the lower limit of 300 for the width is arbitrary OTOH)
//
// NB: we write "n + 2" because the horiz. scrollbar also takes some place
long hListbox = wxMax((n + 2) * heightTextMax, hTotalMsg),
wListbox = wxMax(300, wxMax(wTotalButtons, widthTextMax));
#if wxUSE_STATLINE
// arbitrary...
long hStatLine = 5;
#endif
// now the complete dialog size
// ----------------------------
long hDialog = 2*LAYOUT_Y_MARGIN + // top margin
hTotalMsg + // message
2*LAYOUT_Y_MARGIN + // margin between text and listbox
hListbox + // listbox
#if wxUSE_STATLINE
LAYOUT_Y_MARGIN + // margin
hStatLine + // separator line
#endif
2*LAYOUT_Y_MARGIN + // margin between listbox and buttons
hButton + // button(s)
LAYOUT_Y_MARGIN; // bottom margin
long wDialog = wxMax(wTotalButtons, widthTextMax) +
4*LAYOUT_X_MARGIN; // 2 from each side
// create the controls
// -------------------
// message
wxStaticText *text;
int y = 2*LAYOUT_Y_MARGIN;
for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
{
text = new wxStaticText(this, -1, lines[nLine],
wxPoint(2*LAYOUT_X_MARGIN, y),
wxSize(widthTextMax, heightTextMax));
y += heightTextMax;
}
y += 2*LAYOUT_X_MARGIN;
// listbox
m_listbox = new wxListBox( this, wxID_LISTBOX,
wxPoint(2*LAYOUT_X_MARGIN, y),
wxSize(wListbox, hListbox),
n, choices,
wxLB_HSCROLL);
y += hListbox;
wxListBox *listBox = new wxListBox( this, wxID_LISTBOX, wxPoint(10, y), wxSize(340, listbox_height),
n, choices, wxLB_ALWAYS_SB );
listBox->SetSelection( m_selection );
if ( clientData ) if ( clientData )
{ {
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
listBox->SetClientData(i, clientData[i]); m_listbox->SetClientData(i, clientData[i]);
}
y += listbox_height + 35;
if (style & wxOK)
{
ok = new wxButton( this, wxID_OK, _("OK"), wxPoint(-1,y), wxSize(80,-1) );
m_buttons.Append( ok );
}
if (style & wxCANCEL)
{
cancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxPoint(-1,y), wxSize(80,-1) );
m_buttons.Append( cancel );
}
if (ok)
{
ok->SetDefault();
ok->SetFocus();
}
int w = m_buttons.GetCount() * 100;
if (message_size.x > w) w = message_size.x;
int space = w / (m_buttons.GetCount()*2);
listBox->SetSize( 20, -1, w-10, listbox_height );
int m = 0;
wxNode *node = m_buttons.First();
while (node)
{
wxWindow *win = (wxWindow*)node->Data();
int x = (m*2+1)*space - 40 + 15;
win->Move( x, -1 );
node = node->Next();
m++;
} }
// separator line
#if wxUSE_STATLINE #if wxUSE_STATLINE
(void) new wxStaticLine( this, -1, wxPoint(0,y-20), wxSize(w+30, 5) ); (void) new wxStaticLine( this, -1,
wxPoint(0, y + LAYOUT_Y_MARGIN),
wxSize(wDialog, hStatLine) );
y += LAYOUT_Y_MARGIN + hStatLine;
#endif #endif
SetSize( w+30, y+40 ); // buttons
y += 2*LAYOUT_X_MARGIN;
// NB: create [Ok] first to get the right tab order
wxButton *ok = (wxButton *) NULL;
wxButton *cancel = (wxButton *) NULL;
long x = wDialog / 2;
if ( hasCancel )
x -= MARGIN_BETWEEN_BUTTONS / 2 + wButton;
else
x -= wButton / 2;
ok = new wxButton( this, wxID_OK, labelOk,
wxPoint(x, y),
wxSize(wButton, hButton) );
if ( hasCancel )
{
x += MARGIN_BETWEEN_BUTTONS + wButton;
cancel = new wxButton( this, wxID_CANCEL, labelCancel,
wxPoint(x, y),
wxSize(wButton, hButton) );
}
ok->SetDefault();
ok->SetFocus();
SetClientSize( wDialog, hDialog );
Centre( wxBOTH ); Centre( wxBOTH );
wxEndBusyCursor();
return TRUE; return TRUE;
} }
// Set the selection // Set the selection
void wxSingleChoiceDialog::SetSelection(int sel) void wxSingleChoiceDialog::SetSelection(int sel)
{ {
wxListBox *listBox = (wxListBox *)FindWindow(wxID_LISTBOX); m_listbox->SetSelection(sel);
if (listBox)
{
listBox->SetSelection(sel);
}
m_selection = sel; m_selection = sel;
} }
void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event)) void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{ {
wxListBox *listBox = (wxListBox *)FindWindow(wxID_LISTBOX); m_selection = m_listbox->GetSelection();
if ( listBox ) m_stringSelection = m_listbox->GetStringSelection();
{ m_clientData = m_listbox->GetClientData(m_selection);
m_selection = listBox->GetSelection();
m_stringSelection = listBox->GetStringSelection();
m_clientData = (wxChar*)listBox->GetClientData(m_selection);
}
EndModal(wxID_OK); EndModal(wxID_OK);
} }
void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event)) void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
{ {
wxListBox *listBox = (wxListBox *)FindWindow(wxID_LISTBOX); m_selection = m_listbox->GetSelection();
if ( listBox ) m_stringSelection = m_listbox->GetStringSelection();
{ m_clientData = m_listbox->GetClientData(m_selection);
m_selection = listBox->GetSelection();
m_stringSelection = listBox->GetStringSelection();
m_clientData = (wxChar*)listBox->GetClientData(m_selection);
}
EndModal(wxID_OK); EndModal(wxID_OK);
} }

View File

@@ -68,6 +68,11 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
wxLayoutConstraints *c; wxLayoutConstraints *c;
wxClientDC dc(this);
dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
long widthText;
dc.GetTextExtent(message, &widthText, NULL);
m_msg = new wxStaticText(this, -1, message); m_msg = new wxStaticText(this, -1, message);
c = new wxLayoutConstraints; c = new wxLayoutConstraints;
c->left.SameAs(this, wxLeft, 10); c->left.SameAs(this, wxLeft, 10);
@@ -113,8 +118,11 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
// calc the height of the dialog // calc the height of the dialog
Fit(); Fit();
// and set the width from it // and set the width from it - unfortunately, Fit() makes the dialog way too
// wide under Windows, so try to find a reasonable value for the width, not
// too big and not too small
wxSize size = GetClientSize(); wxSize size = GetClientSize();
size.x = 2*widthText;
if ( size.x < 2*size.y ) if ( size.x < 2*size.y )
SetClientSize(2*size.y, size.y); SetClientSize(2*size.y, size.y);

View File

@@ -123,7 +123,7 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
// resizeable or not (but a resizeable dialog always has caption - // resizeable or not (but a resizeable dialog always has caption -
// otherwise it would look too strange) // otherwise it would look too strange)
const wxChar *dlg; const wxChar *dlg;
if ( style & wxTHICK_FRAME ) if ( style & wxRESIZE_BORDER )
dlg = _T("wxResizeableDialog"); dlg = _T("wxResizeableDialog");
else if ( style & wxCAPTION ) else if ( style & wxCAPTION )
dlg = _T("wxCaptionDialog"); dlg = _T("wxCaptionDialog");