From fe8635a7e78715344f0f4b6abc9d797931429333 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sat, 9 Sep 2006 13:36:54 +0000 Subject: [PATCH] Applied wxGauge:Pulse() patch. [ 1551409 ] Support for indeterminate mode gauges git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41089 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 12 ------- include/wx/gauge.h | 18 ++++++++-- include/wx/generic/progdlgg.h | 9 +++++ include/wx/gtk/gauge.h | 10 ++++-- include/wx/mac/carbon/gauge.h | 3 ++ include/wx/mac/classic/gauge.h | 2 ++ include/wx/progdlg.h | 13 +++++++ src/common/gaugecmn.cpp | 38 ++++++++++++++++++++- src/generic/progdlgg.cpp | 62 +++++++++++++++++++++++++++++----- src/gtk/gauge.cpp | 8 +++++ src/mac/carbon/gauge.cpp | 8 +++++ src/mac/classic/gauge.cpp | 5 +++ src/msw/gauge95.cpp | 56 ++++++++++++++++++++++++++++++ 13 files changed, 219 insertions(+), 25 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index ce6b9e9575..18d47edfb5 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1656,18 +1656,6 @@ enum wxBorder #define wxLI_HORIZONTAL wxHORIZONTAL #define wxLI_VERTICAL wxVERTICAL -/* - * wxProgressDialog flags - */ -#define wxPD_CAN_ABORT 0x0001 -#define wxPD_APP_MODAL 0x0002 -#define wxPD_AUTO_HIDE 0x0004 -#define wxPD_ELAPSED_TIME 0x0008 -#define wxPD_ESTIMATED_TIME 0x0010 -#define wxPD_SMOOTH 0x0020 -#define wxPD_REMAINING_TIME 0x0040 -#define wxPD_CAN_SKIP 0x0080 - /* * extended dialog specifiers. these values are stored in a different diff --git a/include/wx/gauge.h b/include/wx/gauge.h index cb1cffb25b..61dd3fa1f6 100644 --- a/include/wx/gauge.h +++ b/include/wx/gauge.h @@ -33,6 +33,13 @@ #define wxGA_PROGRESSBAR 0 #endif // WXWIN_COMPATIBILITY_2_6 +// GTK and Mac always have native implementation of the indeterminate mode +// wxMSW has native implementation only if comctl32.dll >= 6.00 +#if !defined(__WXGTK20__) && !defined(__WXMAC__) && !defined(__WXCOCOA__) + #define wxGAUGE_EMULATE_INDETERMINATE_MODE 1 +#else + #define wxGAUGE_EMULATE_INDETERMINATE_MODE 0 +#endif extern WXDLLEXPORT_DATA(const wxChar) wxGaugeNameStr[]; @@ -55,18 +62,21 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxGaugeNameStr); + // determinate mode API + // set/get the control range virtual void SetRange(int range); virtual int GetRange() const; - // position virtual void SetValue(int pos); virtual int GetValue() const; + // indeterminate mode API + virtual void Pulse(); + // simple accessors bool IsVertical() const { return HasFlag(wxGA_VERTICAL); } - // appearance params (not implemented for most ports) virtual void SetShadowWidth(int w); virtual int GetShadowWidth() const; @@ -84,6 +94,10 @@ protected: // the current position int m_gaugePos; +#if wxGAUGE_EMULATE_INDETERMINATE_MODE + int m_nDirection; // can be wxRIGHT or wxLEFT +#endif + DECLARE_NO_COPY_CLASS(wxGaugeBase) }; diff --git a/include/wx/generic/progdlgg.h b/include/wx/generic/progdlgg.h index 81fda8c37e..44467b1836 100644 --- a/include/wx/generic/progdlgg.h +++ b/include/wx/generic/progdlgg.h @@ -13,6 +13,7 @@ #define __PROGDLGH_G__ #include "wx/defs.h" +#include "wx/progdlg.h" #if wxUSE_PROGRESSDLG @@ -52,6 +53,11 @@ public: @returns true if ABORT button has not been pressed */ virtual bool Update(int value, const wxString& newmsg = wxEmptyString, bool *skip = NULL); + + /* Switches the dialog to use a gauge in indeterminate mode and calls + wxGauge::Pulse() to show to the user a bit of progress */ + virtual bool UpdatePulse(const wxString& newmsg = wxEmptyString, bool *skip = NULL); + // Must provide overload to avoid hiding it (and warnings about it) virtual void Update() { wxDialog::Update(); } @@ -82,6 +88,9 @@ private: // as the next windows in the sizer, returns the created control wxStaticText *CreateLabel(const wxString& text, wxSizer *sizer); + // updates the label message + void UpdateMessage(const wxString &newmsg); + // shortcuts for enabling buttons void EnableClose(); void EnableSkip(bool enable=true); diff --git a/include/wx/gtk/gauge.h b/include/wx/gtk/gauge.h index 8b78986b65..5a53a9aadf 100644 --- a/include/wx/gtk/gauge.h +++ b/include/wx/gtk/gauge.h @@ -43,13 +43,19 @@ public: void SetShadowWidth( int WXUNUSED(w) ) { } void SetBezelFace( int WXUNUSED(w) ) { } - void SetRange( int r ); - void SetValue( int pos ); int GetShadowWidth() const { return 0; }; int GetBezelFace() const { return 0; }; + + // determinate mode API + void SetRange( int r ); + void SetValue( int pos ); + int GetRange() const; int GetValue() const; + // indeterminate mode API + virtual void Pulse(); + bool IsVertical() const { return HasFlag(wxGA_VERTICAL); } static wxVisualAttributes diff --git a/include/wx/mac/carbon/gauge.h b/include/wx/mac/carbon/gauge.h index 97109b1459..b75005c4b7 100644 --- a/include/wx/mac/carbon/gauge.h +++ b/include/wx/mac/carbon/gauge.h @@ -45,6 +45,9 @@ class WXDLLEXPORT wxGauge: public wxGaugeBase virtual void SetRange(int range); virtual void SetValue(int pos); virtual int GetValue() const ; + + void Pulse(); + protected: DECLARE_DYNAMIC_CLASS_NO_COPY(wxGauge) }; diff --git a/include/wx/mac/classic/gauge.h b/include/wx/mac/classic/gauge.h index 926226de32..4d262e12ad 100644 --- a/include/wx/mac/classic/gauge.h +++ b/include/wx/mac/classic/gauge.h @@ -52,6 +52,8 @@ class WXDLLEXPORT wxGauge: public wxGaugeBase int GetRange() const ; int GetValue() const ; + void Pulse(); + virtual void Command(wxCommandEvent& WXUNUSED(event)) {} ; protected: diff --git a/include/wx/progdlg.h b/include/wx/progdlg.h index e38c9cef8f..dbce6e7275 100644 --- a/include/wx/progdlg.h +++ b/include/wx/progdlg.h @@ -14,6 +14,19 @@ #include "wx/defs.h" +/* + * wxProgressDialog flags + */ +#define wxPD_CAN_ABORT 0x0001 +#define wxPD_APP_MODAL 0x0002 +#define wxPD_AUTO_HIDE 0x0004 +#define wxPD_ELAPSED_TIME 0x0008 +#define wxPD_ESTIMATED_TIME 0x0010 +#define wxPD_SMOOTH 0x0020 +#define wxPD_REMAINING_TIME 0x0040 +#define wxPD_CAN_SKIP 0x0080 + + #ifdef __WXPALMOS__ #include "wx/palmos/progdlg.h" #else diff --git a/src/common/gaugecmn.cpp b/src/common/gaugecmn.cpp index 49d5b59144..a41d08ef3e 100644 --- a/src/common/gaugecmn.cpp +++ b/src/common/gaugecmn.cpp @@ -66,12 +66,15 @@ bool wxGaugeBase::Create(wxWindow *parent, SetRange(range); SetValue(0); +#if wxGAUGE_EMULATE_INDETERMINATE_MODE + m_nDirection = wxRIGHT; +#endif return true; } // ---------------------------------------------------------------------------- -// wxGauge range/position +// wxGauge determinate mode range/position // ---------------------------------------------------------------------------- void wxGaugeBase::SetRange(int range) @@ -94,6 +97,39 @@ int wxGaugeBase::GetValue() const return m_gaugePos; } +// ---------------------------------------------------------------------------- +// wxGauge indeterminate mode +// ---------------------------------------------------------------------------- + +void wxGaugeBase::Pulse() +{ +#if wxGAUGE_EMULATE_INDETERMINATE_MODE + // simulate indeterminate mode + int curr = GetValue(), max = GetRange(); + + if (m_nDirection == wxRIGHT) + { + if (curr < max) + SetValue(curr + 1); + else + { + SetValue(max - 1); + m_nDirection = wxLEFT; + } + } + else + { + if (curr > 0) + SetValue(curr - 1); + else + { + SetValue(1); + m_nDirection = wxRIGHT; + } + } +#endif +} + // ---------------------------------------------------------------------------- // wxGauge appearance params // ---------------------------------------------------------------------------- diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index 91d6bec43c..cffe7fce24 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -40,7 +40,7 @@ #include "wx/settings.h" #endif -#include "wx/generic/progdlgg.h" +#include "wx/progdlg.h" // --------------------------------------------------------------------------- // macros @@ -308,7 +308,7 @@ wxStaticText *wxProgressDialog::CreateLabel(const wxString& text, locsizer->Add(dummy, 1, wxALIGN_LEFT); locsizer->Add(label, 1, wxALIGN_LEFT); sizer->Add(locsizer, 0, wxALIGN_LEFT | wxTOP | wxLEFT, LAYOUT_MARGIN); -#elif defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMAC__) +#elif defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMAC__) || defined(__WXGTK20__) // label and time centered in one row locsizer->Add(dummy, 1, wxLARGESMALL(wxALIGN_RIGHT,wxALIGN_LEFT)); locsizer->Add(label, 1, wxALIGN_LEFT | wxLEFT, LAYOUT_MARGIN); @@ -345,12 +345,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) m_gauge->SetValue(value == m_maximum ? value : value + 1); } - if ( !newmsg.empty() && newmsg != m_msg->GetLabel() ) - { - m_msg->SetLabel(newmsg); - - wxYieldIfNeeded() ; - } + UpdateMessage(newmsg); if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) ) { @@ -463,6 +458,39 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) return m_state != Canceled; } +bool +wxProgressDialog::UpdatePulse(const wxString& newmsg, bool *skip) +{ + wxASSERT_MSG( m_gauge, wxT("cannot update non existent dialog") ); + + // show a bit of progress + m_gauge->Pulse(); + + UpdateMessage(newmsg); + + if (m_elapsed || m_remaining || m_estimated) + { + unsigned long elapsed = wxGetCurrentTime() - m_timeStart; + + SetTimeLabel(elapsed, m_elapsed); + SetTimeLabel((unsigned long)-1, m_estimated); + SetTimeLabel((unsigned long)-1, m_remaining); + } + + // we have to yield because not only we want to update the display but + // also to process the clicks on the cancel and skip buttons + wxYieldIfNeeded() ; + + if ( (m_skip) && (skip != NULL) && (*skip == false) ) + { + *skip = true; + m_skip = false; + EnableSkip(); + } + + return m_state != Canceled; +} + void wxProgressDialog::Resume() { m_state = Continue; @@ -575,10 +603,18 @@ static void SetTimeLabel(unsigned long val, wxStaticText *label) if ( label ) { wxString s; + + if (val != (unsigned long)-1) + { unsigned long hours = val / 3600; unsigned long minutes = (val % 3600) / 60; unsigned long seconds = val % 60; s.Printf(wxT("%lu:%02lu:%02lu"), hours, minutes, seconds); + } + else + { + s = _("Unknown"); + } if ( s != label->GetLabel() ) label->SetLabel(s); @@ -633,4 +669,14 @@ void wxProgressDialog::EnableClose() } } +void wxProgressDialog::UpdateMessage(const wxString &newmsg) +{ + if ( !newmsg.empty() && newmsg != m_msg->GetLabel() ) + { + m_msg->SetLabel(newmsg); + + wxYieldIfNeeded() ; + } +} + #endif // wxUSE_PROGRESSDLG diff --git a/src/gtk/gauge.cpp b/src/gtk/gauge.cpp index 25beb33bbe..e0b4b49010 100644 --- a/src/gtk/gauge.cpp +++ b/src/gtk/gauge.cpp @@ -49,6 +49,9 @@ bool wxGauge::Create( wxWindow *parent, GTK_PROGRESS_BOTTOM_TO_TOP ); } + // when using the gauge in indeterminate mode, we need this: + gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR (m_widget), 0.05); + m_parent->DoAddChild( this ); PostCreation(size); @@ -105,6 +108,11 @@ int wxGauge::GetValue() const return m_gaugePos; } +void wxGauge::Pulse() +{ + gtk_progress_bar_pulse(GTK_PROGRESS_BAR (m_widget)); +} + wxVisualAttributes wxGauge::GetDefaultAttributes() const { // Visible gauge colours use a different colour state diff --git a/src/mac/carbon/gauge.cpp b/src/mac/carbon/gauge.cpp index 9fa85e7746..531cf003f3 100644 --- a/src/mac/carbon/gauge.cpp +++ b/src/mac/carbon/gauge.cpp @@ -95,5 +95,13 @@ int wxGauge::GetValue() const return m_gaugePos ; } +void wxGauge::Pulse() +{ + if ( m_peer && m_peer->Ok() ) + { + // need to use the animate() method of NSProgressIndicator Class here + } +} + #endif // wxUSE_GAUGE diff --git a/src/mac/classic/gauge.cpp b/src/mac/classic/gauge.cpp index f821220971..5dbb9f1a23 100644 --- a/src/mac/classic/gauge.cpp +++ b/src/mac/classic/gauge.cpp @@ -72,6 +72,11 @@ void wxGauge::SetValue(int pos) ::SetControl32BitValue( (ControlHandle) m_macControl , m_gaugePos ) ; } +void wxGauge::Pulse() +{ + // need to use the animate() method of NSProgressIndicator Class here +} + int wxGauge::GetShadowWidth() const { return 0; diff --git a/src/msw/gauge95.cpp b/src/msw/gauge95.cpp index 4d79cb7867..f453f37805 100644 --- a/src/msw/gauge95.cpp +++ b/src/msw/gauge95.cpp @@ -55,6 +55,14 @@ #define PBM_SETBKCOLOR 0x2001 #endif +#ifndef PBS_MARQUEE + #define PBS_MARQUEE 0x08 +#endif + +#ifndef PBM_SETMARQUEE + #define PBM_SETMARQUEE (WM_USER+10) +#endif + // ---------------------------------------------------------------------------- // wxWin macros // ---------------------------------------------------------------------------- @@ -142,6 +150,9 @@ bool wxGauge95::Create(wxWindow *parent, SetRange(range); + // in case we need to emulate indeterminate mode... + m_nDirection = wxRIGHT; + return true; } @@ -178,6 +189,9 @@ wxSize wxGauge95::DoGetBestSize() const void wxGauge95::SetRange(int r) { + // switch to determinate mode if required + SetDeterminateMode(); + m_rangeMax = r; #ifdef PBM_SETRANGE32 @@ -190,6 +204,9 @@ void wxGauge95::SetRange(int r) void wxGauge95::SetValue(int pos) { + // switch to determinate mode if required + SetDeterminateMode(); + m_gaugePos = pos; ::SendMessage(GetHwnd(), PBM_SETPOS, pos, 0); @@ -215,4 +232,43 @@ bool wxGauge95::SetBackgroundColour(const wxColour& col) return true; } +void wxGauge95::SetIndeterminateMode() +{ + // add the PBS_MARQUEE style to the progress bar + LONG style = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ((style & PBS_MARQUEE) == 0) + ::SetWindowLong(GetHwnd(), GWL_STYLE, style|PBS_MARQUEE); + + // now the control can only run in indeterminate mode +} + +void wxGauge95::SetDeterminateMode() +{ + // remove the PBS_MARQUEE style to the progress bar + LONG style = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ((style & PBS_MARQUEE) != 0) + ::SetWindowLong(GetHwnd(), GWL_STYLE, style & ~PBS_MARQUEE); + + // now the control can only run in determinate mode +} + +void wxGauge95::Pulse() +{ + if (wxApp::GetComCtl32Version() >= 600) + { + // switch to indeterminate mode if required + SetIndeterminateMode(); + + // NOTE: when in indeterminate mode, the PBM_SETPOS message will just make + // the bar's blocks move a bit and the WPARAM value is just ignored + // so that we can safely use zero + SendMessage(GetHwnd(), (UINT) PBM_SETPOS, (WPARAM)0, (LPARAM)0); + } + else + { + // emulate indeterminate mode + wxGaugeBase::Pulse(); + } +} + #endif // wxUSE_GAUGE -- 2.45.2