From: Włodzimierz Skiba Date: Thu, 30 Dec 2004 15:07:28 +0000 (+0000) Subject: wxPD_CAN_SKIP for skipping parts of progress and reintroduced wxPD_SMOOTH after remov... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/ecda94753af66cb77d88fbf68be5de14193a5925?ds=sidebyside 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 --- diff --git a/docs/changes.txt b/docs/changes.txt index 9883a6d835..c40943cf5c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -45,6 +45,9 @@ All (GUI): book control (for now wxChoicebook for MSSmartphone, wxNotebook for others). Necessary event macros, types and styles mapped accordingly. - 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: diff --git a/docs/latex/wx/progdlg.tex b/docs/latex/wx/progdlg.tex index 0bdf7f669b..d0d74d7e24 100644 --- a/docs/latex/wx/progdlg.tex +++ b/docs/latex/wx/progdlg.tex @@ -49,9 +49,13 @@ window is disabled, but not to the other ones.} \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 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 "Cancel" button which the user may press. If this happens, the next call to \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\_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.} @@ -77,7 +81,8 @@ ABORT. \func{virtual bool}{Update}{ \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 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.} \docparam{newmsg}{The new messages for the progress dialog text, if it is 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.} diff --git a/include/wx/defs.h b/include/wx/defs.h index 11d1711a22..9f088c3832 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1531,10 +1531,9 @@ enum wxBorder #define wxPD_AUTO_HIDE 0x0004 #define wxPD_ELAPSED_TIME 0x0008 #define wxPD_ESTIMATED_TIME 0x0010 -/* wxGA_SMOOTH = 0x0020 may also be used with wxProgressDialog */ -/* NO!!! This is wxDIALOG_MODAL and will cause the progress dialog to */ -/* be modal. No progress will then be made at all. */ +#define wxPD_SMOOTH 0x0020 #define wxPD_REMAINING_TIME 0x0040 +#define wxPD_CAN_SKIP 0x0080 /* * wxDirDialog styles diff --git a/include/wx/generic/progdlgg.h b/include/wx/generic/progdlgg.h index e53d3af732..6444697cec 100644 --- a/include/wx/generic/progdlgg.h +++ b/include/wx/generic/progdlgg.h @@ -16,7 +16,7 @@ #pragma interface "progdlgg.h" #endif -#include "wx/setup.h" +#include "wx/defs.h" #if wxUSE_PROGRESSDLG @@ -55,7 +55,7 @@ public: @param newmsg if used, new message to display @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 the program decided to continue the operation (e.g., user didn't @@ -69,6 +69,9 @@ protected: // callback for optional abort button void OnCancel(wxCommandEvent& event); + // callback for optional skip button + void OnSkip(wxCommandEvent& event); + // callback to disable "hard" window closing void OnClose(wxCloseEvent& event); @@ -108,8 +111,14 @@ private: Finished // finished, waiting to be removed from screen } 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_btnSkip; +#endif // the maximum value int m_maximum; diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index dc43589120..8e551bdc64 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -575,7 +575,7 @@ void MyFrame::PasswordEntry(wxCommandEvent& WXUNUSED(event)) _T("Password entry dialog"), wxEmptyString, this); - if ( !!pwd ) + if ( !pwd.empty() ) { wxMessageBox(wxString::Format(wxT("Your password is '%s'"), pwd.c_str()), _T("Got password"), wxOK | wxICON_INFORMATION, this); @@ -990,14 +990,18 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) max, // range this, // parent wxPD_CAN_ABORT | + wxPD_CAN_SKIP | wxPD_APP_MODAL | // wxPD_AUTO_HIDE | -- try this as well wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | - wxPD_REMAINING_TIME); + wxPD_REMAINING_TIME | + wxPD_SMOOTH); 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 // do (almost) the same operations as we did for the performance test @@ -1018,25 +1022,27 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) #else wxSleep(1); #endif + + wxString msg; + 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 ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster { - #if wxUSE_STOPWATCH && wxUSE_LONGLONG - if ( (i % (max/100)) == 0 ) // // only 100 updates, this makes it much faster - { - cont = dialog.Update(i); - } - #else - cont = dialog.Update(i); - #endif + cont = dialog.Update(i, msg, &skip); } +#else + cont = dialog.Update(i, msg, &skip); +#endif + if ( !cont ) { if ( wxMessageBox(_T("Do you really want to cancel?"), diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index 5dbc359334..c6e1ff2422 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -66,6 +66,8 @@ #define LAYOUT_MARGIN wxLARGESMALL(8,2) +static const int wxID_SKIP = 32000; // whatever + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -79,6 +81,7 @@ static void SetTimeLabel(unsigned long val, wxStaticText *label); BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog) EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel) + EVT_BUTTON(wxID_SKIP, wxProgressDialog::OnSkip) EVT_CLOSE(wxProgressDialog::OnClose) END_EVENT_TABLE() @@ -99,14 +102,15 @@ wxProgressDialog::wxProgressDialog(wxString const &title, wxWindow *parent, int style) : 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 SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT); - m_windowStyle |= style; bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0; + bool hasSkipButton = (style & wxPD_CAN_SKIP) != 0; #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) // 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 ) { - // note that we can't use wxGA_SMOOTH because it happens to - // cause the dialog to be modal. Have an extra - // style argument to wxProgressDialog, perhaps. + int gauge_style = wxGA_HORIZONTAL; + if ( ( style & wxPD_SMOOTH ) == wxPD_SMOOTH ) + gauge_style |= wxGA_SMOOTH; m_gauge = new wxGauge(this, wxID_ANY, m_maximum, wxDefaultPosition, wxDefaultSize, - wxGA_HORIZONTAL); + gauge_style ); sizer->Add(m_gauge, 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 2*LAYOUT_MARGIN); m_gauge->SetValue(0); @@ -209,28 +213,47 @@ wxProgressDialog::wxProgressDialog(wxString const &title, sizeDlg.y += nTimeLabels * (label->GetSize().y + LAYOUT_MARGIN); } - if ( hasAbortButton ) - { #if defined(__SMARTPHONE__) - SetLeftMenu(wxID_CANCEL, _("Cancel")); - } + if ( hasSkipButton ) + SetRightMenu(wxID_SKIP, _("Skip")); + if ( hasAbortButton ) + SetLeftMenu(wxID_CANCEL); #else - m_btnAbort = new wxButton(this, wxID_CANCEL); + m_btnAbort = m_btnSkip = (wxButton *)NULL; + bool sizeDlgModified = false; + wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL); - // Windows dialogs usually have buttons in the lower right corner + const int sizerFlags = #if defined(__WXMSW__) || defined(__WXPM__) - sizer->Add(m_btnAbort, 0, wxALIGN_RIGHT | wxALL, 2*LAYOUT_MARGIN); + wxALIGN_RIGHT | wxALL #else // !MSW - sizer->Add(m_btnAbort, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxTOP, 2*LAYOUT_MARGIN); + 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; } - else // no "Cancel" button -#endif // __SMARTPHONE__/!__SMARTPHONE__ + + if ( hasAbortButton ) { - m_btnAbort = (wxButton *)NULL; + m_btnAbort = new wxButton(this, wxID_CANCEL); + + // Windows dialogs usually have buttons in the lower right corner + buttonSizer->Add(m_btnAbort, 0, sizerFlags, LAYOUT_MARGIN); + if(!sizeDlgModified) + sizeDlg.y += 2*LAYOUT_MARGIN + wxButton::GetDefaultSize().y; } + sizer->Add(buttonSizer, 0, sizerFlags, LAYOUT_MARGIN ); +#endif // __SMARTPHONE__/!__SMARTPHONE__ + SetSizerAndFit(sizer); sizeDlg.y += 2*LAYOUT_MARGIN; @@ -302,7 +325,7 @@ wxStaticText *wxProgressDialog::CreateLabel(const wxString& text, // ---------------------------------------------------------------------------- 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") ); @@ -319,7 +342,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg) m_gauge->SetValue(value == m_maximum ? value : value + 1); } - if ( !newmsg.IsEmpty() ) + if ( !newmsg.empty() && newmsg != m_msg->GetLabel() ) { m_msg->SetLabel(newmsg); @@ -393,7 +416,14 @@ wxProgressDialog::Update(int value, const wxString& newmsg) { #if defined(__SMARTPHONE__) SetLeftMenu(wxID_CANCEL, _("Close")); + SetRightMenu(); #endif + if ( m_btnSkip ) + { + // tell the user what he should do... + m_btnSkip->Disable(); + } + if ( m_btnAbort ) { // tell the user what he should do... @@ -406,7 +436,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg) } #endif // __WXMSW__ - if ( !newmsg ) + if ( !newmsg.empty() ) { // also provide the finishing message if the application didn't m_msg->SetLabel(_("Done.")); @@ -429,8 +459,16 @@ wxProgressDialog::Update(int value, const wxString& newmsg) else { // 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() ; + + 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 @@ -449,6 +487,12 @@ void wxProgressDialog::Resume() // user interrupt us again if needed if(m_btnAbort) 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__) SetLeftMenu(wxID_CANCEL, _("Cancel")); #endif @@ -487,6 +531,8 @@ void wxProgressDialog::OnCancel(wxCommandEvent& event) // request has been noticed if(m_btnAbort) m_btnAbort->Disable(); + if(m_btnSkip) + m_btnSkip->Disable(); #if defined(__SMARTPHONE__) 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) { if ( m_state == Uncancelable ) @@ -515,6 +568,9 @@ void wxProgressDialog::OnClose(wxCloseEvent& event) m_state = Canceled; if(m_btnAbort) m_btnAbort->Disable(); + if(m_btnSkip) + m_btnSkip->Disable(); + #if defined(__SMARTPHONE__) SetLeftMenu(); #endif