wxPD_CAN_SKIP for skipping parts of progress and reintroduced wxPD_SMOOTH after removal of modal dialog flag.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31193 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Włodzimierz Skiba
2004-12-30 15:07:28 +00:00
parent e7b97da356
commit ecda94753a
6 changed files with 126 additions and 46 deletions

View File

@@ -45,6 +45,9 @@ All (GUI):
book control (for now wxChoicebook for MSSmartphone, wxNotebook for others). book control (for now wxChoicebook for MSSmartphone, wxNotebook for others).
Necessary event macros, types and styles mapped accordingly. Necessary event macros, types and styles mapped accordingly.
- new wxBrush::IsHatch() checking for brush type replaces IS_HATCH macro - new wxBrush::IsHatch() checking for brush type replaces IS_HATCH macro
- wxProgressDialog accepts smooth gauge again (wxPD_SMOOTH style)
- wxProgressDialog new style: wxPD_CAN_SKIP which provides skipping some parts
of the progress (with new "Skip" button in dialog)
Unix: Unix:

View File

@@ -49,9 +49,13 @@ window is disabled, but not to the other ones.}
\twocolitem{{\bf wxPD\_AUTO\_HIDE}}{Causes the progress dialog to disappear \twocolitem{{\bf wxPD\_AUTO\_HIDE}}{Causes the progress dialog to disappear
from screen as soon as the maximum value of the progress meter has been from screen as soon as the maximum value of the progress meter has been
reached.} reached.}
\twocolitem{{\bf wxPD\_SMOOTH}}{Causes smooth progress of the gauge control.}
\twocolitem{{\bf wxPD\_CAN\_ABORT}}{This flag tells the dialog that it should have a \twocolitem{{\bf wxPD\_CAN\_ABORT}}{This flag tells the dialog that it should have a
"Cancel" button which the user may press. If this happens, the next call to "Cancel" button which the user may press. If this happens, the next call to
\helpref{Update()}{wxprogressdialogupdate} will return false.} \helpref{Update()}{wxprogressdialogupdate} will return false.}
\twocolitem{{\bf wxPD\_CAN\_SKIP}}{This flag tells the dialog that it should have a
"Skip" button which the user may press. If this happens, the next call to
\helpref{Update()}{wxprogressdialogupdate} will return true in its skip parameter.}
\twocolitem{{\bf wxPD\_ELAPSED\_TIME}}{This flag tells the dialog that it should show elapsed time (since creating the dialog).} \twocolitem{{\bf wxPD\_ELAPSED\_TIME}}{This flag tells the dialog that it should show elapsed time (since creating the dialog).}
\twocolitem{{\bf wxPD\_ESTIMATED\_TIME}}{This flag tells the dialog that it should show estimated time.} \twocolitem{{\bf wxPD\_ESTIMATED\_TIME}}{This flag tells the dialog that it should show estimated time.}
\twocolitem{{\bf wxPD\_REMAINING\_TIME}}{This flag tells the dialog that it should show remaining time.} \twocolitem{{\bf wxPD\_REMAINING\_TIME}}{This flag tells the dialog that it should show remaining time.}
@@ -77,7 +81,8 @@ ABORT.
\func{virtual bool}{Update}{ \func{virtual bool}{Update}{
\param{int }{value},\rtfsp \param{int }{value},\rtfsp
\param{const wxString\& }{newmsg = ""}} \param{const wxString\& }{newmsg = ""},\rtfsp
\param{bool *}{skip = NULL}}
Updates the dialog, setting the progress bar to the new value and, if Updates the dialog, setting the progress bar to the new value and, if
given changes the message above it. Returns true unless the Cancel button given changes the message above it. Returns true unless the Cancel button
@@ -94,4 +99,6 @@ equal to the maximum value given to the constructor and the dialog is closed if
it is equal to the maximum.} it is equal to the maximum.}
\docparam{newmsg}{The new messages for the progress dialog text, if it is \docparam{newmsg}{The new messages for the progress dialog text, if it is
empty (which is the default) the message is not changed.} empty (which is the default) the message is not changed.}
\docparam{skip}{If "Skip" button was pressed since last
\helpref{Update}{wxprogressdialogupdate} call the skip is true.}

View File

@@ -1531,10 +1531,9 @@ enum wxBorder
#define wxPD_AUTO_HIDE 0x0004 #define wxPD_AUTO_HIDE 0x0004
#define wxPD_ELAPSED_TIME 0x0008 #define wxPD_ELAPSED_TIME 0x0008
#define wxPD_ESTIMATED_TIME 0x0010 #define wxPD_ESTIMATED_TIME 0x0010
/* wxGA_SMOOTH = 0x0020 may also be used with wxProgressDialog */ #define wxPD_SMOOTH 0x0020
/* NO!!! This is wxDIALOG_MODAL and will cause the progress dialog to */
/* be modal. No progress will then be made at all. */
#define wxPD_REMAINING_TIME 0x0040 #define wxPD_REMAINING_TIME 0x0040
#define wxPD_CAN_SKIP 0x0080
/* /*
* wxDirDialog styles * wxDirDialog styles

View File

@@ -16,7 +16,7 @@
#pragma interface "progdlgg.h" #pragma interface "progdlgg.h"
#endif #endif
#include "wx/setup.h" #include "wx/defs.h"
#if wxUSE_PROGRESSDLG #if wxUSE_PROGRESSDLG
@@ -55,7 +55,7 @@ public:
@param newmsg if used, new message to display @param newmsg if used, new message to display
@returns true if ABORT button has not been pressed @returns true if ABORT button has not been pressed
*/ */
virtual bool Update(int value, const wxString& newmsg = wxEmptyString); virtual bool Update(int value, const wxString& newmsg = wxEmptyString, bool *skip = NULL);
/* Can be called to continue after the cancel button has been pressed, but /* Can be called to continue after the cancel button has been pressed, but
the program decided to continue the operation (e.g., user didn't the program decided to continue the operation (e.g., user didn't
@@ -69,6 +69,9 @@ protected:
// callback for optional abort button // callback for optional abort button
void OnCancel(wxCommandEvent& event); void OnCancel(wxCommandEvent& event);
// callback for optional skip button
void OnSkip(wxCommandEvent& event);
// callback to disable "hard" window closing // callback to disable "hard" window closing
void OnClose(wxCloseEvent& event); void OnClose(wxCloseEvent& event);
@@ -108,8 +111,14 @@ private:
Finished // finished, waiting to be removed from screen Finished // finished, waiting to be removed from screen
} m_state; } m_state;
// the abort button (or NULL if none) // skip some portion
bool m_skip;
#if !defined(__SMARTPHONE__)
// the abort and skip buttons (or NULL if none)
wxButton *m_btnAbort; wxButton *m_btnAbort;
wxButton *m_btnSkip;
#endif
// the maximum value // the maximum value
int m_maximum; int m_maximum;

View File

@@ -575,7 +575,7 @@ void MyFrame::PasswordEntry(wxCommandEvent& WXUNUSED(event))
_T("Password entry dialog"), _T("Password entry dialog"),
wxEmptyString, wxEmptyString,
this); this);
if ( !!pwd ) if ( !pwd.empty() )
{ {
wxMessageBox(wxString::Format(wxT("Your password is '%s'"), pwd.c_str()), wxMessageBox(wxString::Format(wxT("Your password is '%s'"), pwd.c_str()),
_T("Got password"), wxOK | wxICON_INFORMATION, this); _T("Got password"), wxOK | wxICON_INFORMATION, this);
@@ -990,14 +990,18 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) )
max, // range max, // range
this, // parent this, // parent
wxPD_CAN_ABORT | wxPD_CAN_ABORT |
wxPD_CAN_SKIP |
wxPD_APP_MODAL | wxPD_APP_MODAL |
// wxPD_AUTO_HIDE | -- try this as well // wxPD_AUTO_HIDE | -- try this as well
wxPD_ELAPSED_TIME | wxPD_ELAPSED_TIME |
wxPD_ESTIMATED_TIME | wxPD_ESTIMATED_TIME |
wxPD_REMAINING_TIME); wxPD_REMAINING_TIME |
wxPD_SMOOTH);
bool cont = true; bool cont = true;
for ( int i = 0; i <= max; i++ ) bool skip = false;
// each skip will move progress about quarter forward
for ( int i = 0; i <= max; i = wxMin(i+(skip?int(max/4):1), max+1), skip = false )
{ {
#if wxUSE_STOPWATCH && wxUSE_LONGLONG #if wxUSE_STOPWATCH && wxUSE_LONGLONG
// do (almost) the same operations as we did for the performance test // do (almost) the same operations as we did for the performance test
@@ -1018,25 +1022,27 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) )
#else #else
wxSleep(1); wxSleep(1);
#endif #endif
wxString msg;
if ( i == max ) if ( i == max )
{ {
cont = dialog.Update(i, _T("That's all, folks!")); msg = _T("That's all, folks!");
} }
else if ( i == max / 2 ) else if ( i > max / 2 )
{ {
cont = dialog.Update(i, _T("Only a half left (very long message)!")); msg = _T("Only a half left (very long message)!");
} }
else
{
#if wxUSE_STOPWATCH && wxUSE_LONGLONG #if wxUSE_STOPWATCH && wxUSE_LONGLONG
if ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster if ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster
{ {
cont = dialog.Update(i); cont = dialog.Update(i, msg, &skip);
} }
#else #else
cont = dialog.Update(i); cont = dialog.Update(i, msg, &skip);
#endif #endif
}
if ( !cont ) if ( !cont )
{ {
if ( wxMessageBox(_T("Do you really want to cancel?"), if ( wxMessageBox(_T("Do you really want to cancel?"),

View File

@@ -66,6 +66,8 @@
#define LAYOUT_MARGIN wxLARGESMALL(8,2) #define LAYOUT_MARGIN wxLARGESMALL(8,2)
static const int wxID_SKIP = 32000; // whatever
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// private functions // private functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -79,6 +81,7 @@ static void SetTimeLabel(unsigned long val, wxStaticText *label);
BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog) BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog)
EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel) EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel)
EVT_BUTTON(wxID_SKIP, wxProgressDialog::OnSkip)
EVT_CLOSE(wxProgressDialog::OnClose) EVT_CLOSE(wxProgressDialog::OnClose)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -99,14 +102,15 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
wxWindow *parent, wxWindow *parent,
int style) int style)
: wxDialog(parent, wxID_ANY, title), : wxDialog(parent, wxID_ANY, title),
m_delay(3) m_delay(3),
m_skip(false)
{ {
// we may disappear at any moment, let the others know about it // we may disappear at any moment, let the others know about it
SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT); SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
m_windowStyle |= style; m_windowStyle |= style;
bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0; bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
bool hasSkipButton = (style & wxPD_CAN_SKIP) != 0;
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
// we have to remove the "Close" button from the title bar then as it is // we have to remove the "Close" button from the title bar then as it is
@@ -151,12 +155,12 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
if ( maximum > 0 ) if ( maximum > 0 )
{ {
// note that we can't use wxGA_SMOOTH because it happens to int gauge_style = wxGA_HORIZONTAL;
// cause the dialog to be modal. Have an extra if ( ( style & wxPD_SMOOTH ) == wxPD_SMOOTH )
// style argument to wxProgressDialog, perhaps. gauge_style |= wxGA_SMOOTH;
m_gauge = new wxGauge(this, wxID_ANY, m_maximum, m_gauge = new wxGauge(this, wxID_ANY, m_maximum,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxGA_HORIZONTAL); gauge_style );
sizer->Add(m_gauge, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 2*LAYOUT_MARGIN); sizer->Add(m_gauge, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 2*LAYOUT_MARGIN);
m_gauge->SetValue(0); m_gauge->SetValue(0);
@@ -209,27 +213,46 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
sizeDlg.y += nTimeLabels * (label->GetSize().y + LAYOUT_MARGIN); sizeDlg.y += nTimeLabels * (label->GetSize().y + LAYOUT_MARGIN);
} }
#if defined(__SMARTPHONE__)
if ( hasSkipButton )
SetRightMenu(wxID_SKIP, _("Skip"));
if ( hasAbortButton )
SetLeftMenu(wxID_CANCEL);
#else
m_btnAbort = m_btnSkip = (wxButton *)NULL;
bool sizeDlgModified = false;
wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
const int sizerFlags =
#if defined(__WXMSW__) || defined(__WXPM__)
wxALIGN_RIGHT | wxALL
#else // !MSW
wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP
#endif // MSW/!MSW
;
if ( hasSkipButton )
{
m_btnSkip = new wxButton(this, wxID_SKIP, _("Skip"));
// Windows dialogs usually have buttons in the lower right corner
buttonSizer->Add(m_btnSkip, 0, sizerFlags, LAYOUT_MARGIN);
sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y;
sizeDlgModified = true;
}
if ( hasAbortButton ) if ( hasAbortButton )
{ {
#if defined(__SMARTPHONE__)
SetLeftMenu(wxID_CANCEL, _("Cancel"));
}
#else
m_btnAbort = new wxButton(this, wxID_CANCEL); m_btnAbort = new wxButton(this, wxID_CANCEL);
// Windows dialogs usually have buttons in the lower right corner // Windows dialogs usually have buttons in the lower right corner
#if defined(__WXMSW__) || defined(__WXPM__) buttonSizer->Add(m_btnAbort, 0, sizerFlags, LAYOUT_MARGIN);
sizer->Add(m_btnAbort, 0, wxALIGN_RIGHT | wxALL, 2*LAYOUT_MARGIN); if(!sizeDlgModified)
#else // !MSW
sizer->Add(m_btnAbort, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP, 2*LAYOUT_MARGIN);
#endif // MSW/!MSW
sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y; sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y;
} }
else // no "Cancel" button
sizer->Add(buttonSizer, 0, sizerFlags, LAYOUT_MARGIN );
#endif // __SMARTPHONE__/!__SMARTPHONE__ #endif // __SMARTPHONE__/!__SMARTPHONE__
{
m_btnAbort = (wxButton *)NULL;
}
SetSizerAndFit(sizer); SetSizerAndFit(sizer);
@@ -302,7 +325,7 @@ wxStaticText *wxProgressDialog::CreateLabel(const wxString& text,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool bool
wxProgressDialog::Update(int value, const wxString& newmsg) wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
{ {
wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") ); wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") );
@@ -319,7 +342,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg)
m_gauge->SetValue(value == m_maximum ? value : value + 1); m_gauge->SetValue(value == m_maximum ? value : value + 1);
} }
if ( !newmsg.IsEmpty() ) if ( !newmsg.empty() && newmsg != m_msg->GetLabel() )
{ {
m_msg->SetLabel(newmsg); m_msg->SetLabel(newmsg);
@@ -393,7 +416,14 @@ wxProgressDialog::Update(int value, const wxString& newmsg)
{ {
#if defined(__SMARTPHONE__) #if defined(__SMARTPHONE__)
SetLeftMenu(wxID_CANCEL, _("Close")); SetLeftMenu(wxID_CANCEL, _("Close"));
SetRightMenu();
#endif #endif
if ( m_btnSkip )
{
// tell the user what he should do...
m_btnSkip->Disable();
}
if ( m_btnAbort ) if ( m_btnAbort )
{ {
// tell the user what he should do... // tell the user what he should do...
@@ -406,7 +436,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg)
} }
#endif // __WXMSW__ #endif // __WXMSW__
if ( !newmsg ) if ( !newmsg.empty() )
{ {
// also provide the finishing message if the application didn't // also provide the finishing message if the application didn't
m_msg->SetLabel(_("Done.")); m_msg->SetLabel(_("Done."));
@@ -429,8 +459,16 @@ wxProgressDialog::Update(int value, const wxString& newmsg)
else else
{ {
// we have to yield because not only we want to update the display but // we have to yield because not only we want to update the display but
// also to process the clicks on the cancel button // also to process the clicks on the cancel and skip buttons
wxYieldIfNeeded() ; wxYieldIfNeeded() ;
if ( (m_skip) && (skip != NULL) && (*skip == false) )
{
*skip = true;
m_skip = false;
if(m_btnSkip)
m_btnSkip->Enable();
}
} }
// update the display in case yielding above didn't do it // update the display in case yielding above didn't do it
@@ -449,6 +487,12 @@ void wxProgressDialog::Resume()
// user interrupt us again if needed // user interrupt us again if needed
if(m_btnAbort) if(m_btnAbort)
m_btnAbort->Enable(); m_btnAbort->Enable();
// enable skipping because the one before OnCancel() is no more valid
m_skip = false;
if(m_btnSkip)
m_btnSkip->Enable();
#if defined(__SMARTPHONE__) #if defined(__SMARTPHONE__)
SetLeftMenu(wxID_CANCEL, _("Cancel")); SetLeftMenu(wxID_CANCEL, _("Cancel"));
#endif #endif
@@ -487,6 +531,8 @@ void wxProgressDialog::OnCancel(wxCommandEvent& event)
// request has been noticed // request has been noticed
if(m_btnAbort) if(m_btnAbort)
m_btnAbort->Disable(); m_btnAbort->Disable();
if(m_btnSkip)
m_btnSkip->Disable();
#if defined(__SMARTPHONE__) #if defined(__SMARTPHONE__)
SetLeftMenu(); SetLeftMenu();
@@ -497,6 +543,13 @@ void wxProgressDialog::OnCancel(wxCommandEvent& event)
} }
} }
void wxProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event))
{
if(m_btnSkip)
m_btnSkip->Disable();
m_skip = true;
}
void wxProgressDialog::OnClose(wxCloseEvent& event) void wxProgressDialog::OnClose(wxCloseEvent& event)
{ {
if ( m_state == Uncancelable ) if ( m_state == Uncancelable )
@@ -515,6 +568,9 @@ void wxProgressDialog::OnClose(wxCloseEvent& event)
m_state = Canceled; m_state = Canceled;
if(m_btnAbort) if(m_btnAbort)
m_btnAbort->Disable(); m_btnAbort->Disable();
if(m_btnSkip)
m_btnSkip->Disable();
#if defined(__SMARTPHONE__) #if defined(__SMARTPHONE__)
SetLeftMenu(); SetLeftMenu();
#endif #endif