#include "wx/dialog.h"
class WXDLLEXPORT wxButton;
+class WXDLLEXPORT wxGauge;
class WXDLLEXPORT wxStaticText;
/* Progress dialog which shows a moving progress bar.
wxStaticText *CreateLabel(const wxString& text, wxWindow **lastWindow);
// the status bar
- class wxGauge *m_gauge;
+ wxGauge *m_gauge;
// the message displayed
- class wxStaticText *m_msg;
- // disable all or parent window only
- bool m_disableParentOnly;
- // auto-hide?
- bool m_AutoHide;
+ wxStaticText *m_msg;
// displayed elapsed, estimated, remaining time
class wxStaticText *m_elapsed,
*m_estimated,
*m_remaining;
// time when the dialog was created
unsigned long m_timeStart;
- // parent window
- wxWindow *m_parent;
+
+ // parent top level window (may be NULL)
+ wxWindow *m_parentTop;
+
// continue processing or not (return value for Update())
enum
{
wxPoint(0, 250), wxSize(100, 50), wxTE_MULTILINE);
m_text->SetBackgroundColour("wheat");
- // wxLog::AddTraceMask(_T("focus"));
+ if ( 0 )
+ wxLog::AddTraceMask(_T("focus"));
m_logTargetOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_text));
m_notebook = new wxNotebook(this, ID_NOTEBOOK);
bool cont = TRUE;
- for ( int i = 0; i < max && cont; i++ )
+ for ( int i = 0; i <= max && cont; i++ )
{
wxSleep(1);
- if ( i == max - 1 )
+ if ( i == max )
{
cont = dialog.Update(i, "That's all, folks!");
}
else if ( i == max / 2 )
{
- cont = dialog.Update(i, "Only a half left!");
+ cont = dialog.Update(i, "Only a half left (very long message)!");
}
else
{
void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
{
- wxBeginBusyCursor();
+ wxBusyCursor bc;
+
+#if 0 // VZ: my temp test code, will remove
+ wxGetTextFromUser("msg", "caption", "val", this);
+ return;
+#endif // 0
wxMessageDialog dialog(this, "This is a control sample", "About Controls", wxOK );
dialog.ShowModal();
-
- wxEndBusyCursor();
}
void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
#include "wx/fontdlg.h"
#include "wx/choicdlg.h"
#include "wx/tipdlg.h"
+#include "wx/progdlg.h"
#define wxTEST_GENERIC_DIALOGS_IN_MSW 0
#if defined(__WXMSW__) && wxTEST_GENERIC_DIALOGS_IN_MSW
EVT_MENU(DIALOGS_CHOOSE_COLOUR_GENERIC, MyFrame::ChooseColourGeneric)
EVT_MENU(DIALOGS_CHOOSE_FONT_GENERIC, MyFrame::ChooseFontGeneric)
+#endif
+#if wxUSE_PROGRESSDLG
+ EVT_MENU(DIALOGS_PROGRESS, MyFrame::ShowProgress)
#endif
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
EVT_BUTTON(DIALOGS_MODELESS_BTN, MyFrame::OnButton)
END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(MyModelessDialog, wxDialog)
+ EVT_CLOSE(MyModelessDialog::OnClose)
+END_EVENT_TABLE()
+
MyCanvas *myCanvas = (MyCanvas *) NULL;
// `Main program' equivalent, creating windows and returning main app frame
file_menu->Append(DIALOGS_FILE_SAVE, "Sa&ve file\tCtrl-S");
file_menu->Append(DIALOGS_DIR_CHOOSE, "&Choose a directory\tCtrl-D");
file_menu->AppendSeparator();
+#if wxUSE_PROGRESSDLG
+ file_menu->Append(DIALOGS_PROGRESS, "Pro&gress dialog\tCtrl-G");
+#endif // wxUSE_PROGRESSDLG
file_menu->Append(DIALOGS_MODELESS, "Modeless &dialog\tCtrl-Z", "", TRUE);
file_menu->AppendSeparator();
file_menu->Append(wxID_EXIT, "E&xit\tAlt-X");
Close(TRUE);
}
+#if wxUSE_PROGRESSDLG
+
+void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) )
+{
+ static const int max = 10;
+
+ wxProgressDialog dialog("Progress dialog example",
+ "An informative message",
+ max, // range
+ this, // parent
+ wxPD_CAN_ABORT |
+ wxPD_APP_MODAL |
+ wxPD_ELAPSED_TIME |
+ wxPD_ESTIMATED_TIME |
+ wxPD_REMAINING_TIME);
+
+ bool cont = TRUE;
+ for ( int i = 0; i <= max && cont; i++ )
+ {
+ wxSleep(1);
+ if ( i == max )
+ {
+ cont = dialog.Update(i, "That's all, folks!");
+ }
+ else if ( i == max / 2 )
+ {
+ cont = dialog.Update(i, "Only a half left (very long message)!");
+ }
+ else
+ {
+ cont = dialog.Update(i);
+ }
+ }
+
+ if ( !cont )
+ {
+ wxLogStatus("Progress dialog aborted!");
+ }
+ else
+ {
+ wxLogStatus("Countdown from %d finished", max);
+ }
+}
+
+#endif // wxUSE_PROGRESSDLG
+
+// ----------------------------------------------------------------------------
+// MyCanvas
+// ----------------------------------------------------------------------------
+
void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event) )
{
wxPaintDC dc(this);
Fit();
Centre();
}
+
+void MyModelessDialog::OnClose(wxCloseEvent& event)
+{
+ if ( event.CanVeto() )
+ {
+ wxMessageBox("Use the menu item to close this dialog",
+ "Modeless dialog",
+ wxOK | wxICON_INFORMATION, this);
+
+ event.Veto();
+ }
+}
+
{
public:
MyModelessDialog(wxWindow *parent);
+
+ void OnClose(wxCloseEvent& event);
+
+private:
+ DECLARE_EVENT_TABLE()
};
// Define a new frame type
void DirChoose(wxCommandEvent& event);
void ShowTip(wxCommandEvent& event);
void ModelessDlg(wxCommandEvent& event);
+ void ShowProgress(wxCommandEvent& event);
#if !defined(__WXMSW__) || wxTEST_GENERIC_DIALOGS_IN_MSW
void ChooseColourGeneric(wxCommandEvent& event);
DIALOGS_NUM_ENTRY,
DIALOGS_LOG_DIALOG,
DIALOGS_MODELESS,
- DIALOGS_MODELESS_BTN
+ DIALOGS_MODELESS_BTN,
+ DIALOGS_PROGRESS
};
#endif
{
bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
m_state = hasAbortButton ? Continue : Uncancelable;
- m_disableParentOnly = (style & wxPD_APP_MODAL) == 0;
- m_AutoHide = (style & wxPD_AUTO_HIDE) != 0;
- m_parent = parent;
m_maximum = maximum;
+ m_parentTop = parent;
+ while ( m_parentTop && m_parentTop->GetParent() )
+ {
+ m_parentTop = m_parentTop->GetParent();
+ }
+
wxLayoutConstraints *c;
wxClientDC dc(this);
Centre(wxCENTER_FRAME | wxBOTH);
- if ( m_disableParentOnly )
+ if ( !(style & wxPD_APP_MODAL) )
{
- if ( m_parent )
- m_parent->Enable(FALSE);
+ if ( m_parentTop )
+ m_parentTop->Enable(FALSE);
}
else
{
bool
wxProgressDialog::Update(int value, const wxString& newmsg)
{
- wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") );
- wxASSERT_MSG( value <= m_maximum, wxT("invalid progress value") );
-
-
- if( m_gauge )
- m_gauge->SetValue(value + 1);
-
- if( !newmsg.IsEmpty() )
- m_msg->SetLabel(newmsg);
-
- if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) )
- {
- unsigned long elapsed = wxGetCurrentTime() - m_timeStart;
- unsigned long estimated = elapsed * m_maximum / value;
- unsigned long remaining = estimated - elapsed;
-
- SetTimeLabel(elapsed, m_elapsed);
- SetTimeLabel(estimated, m_estimated);
- SetTimeLabel(remaining, m_remaining);
- }
-
- if ( (value == m_maximum ) && !m_AutoHide )
- {
- if ( m_btnAbort )
- {
- // tell the user what he should do...
- m_btnAbort->SetLabel(_("Close"));
- }
-
- if ( !newmsg )
- {
- // also provide the finishing message if the application didn't
- m_msg->SetLabel(_("Done."));
- }
-
- // so that we return TRUE below and that out [Cancel] handler knew what
- // to do
- m_state = Finished;
-
- wxYield();
-
- (void)ShowModal();
- }
- else
- {
- // update the display
- wxYield();
- }
+ wxASSERT_MSG( value == -1 || m_gauge, wxT("cannot update non existent dialog") );
+ wxASSERT_MSG( value <= m_maximum, wxT("invalid progress value") );
+
+ if ( m_gauge )
+ m_gauge->SetValue(value + 1);
+
+ if ( !newmsg.IsEmpty() )
+ {
+#ifdef __WXMSW__
+ // this seems to be necessary or garbage is left when the new label is
+ // longer than the old one
+ m_msg->SetLabel(wxEmptyString);
+#endif // MSW
+
+ m_msg->SetLabel(newmsg);
+
+ wxYield();
+ }
+
+ if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) )
+ {
+ unsigned long elapsed = wxGetCurrentTime() - m_timeStart;
+ unsigned long estimated = elapsed * m_maximum / value;
+ unsigned long remaining = estimated - elapsed;
+
+ SetTimeLabel(elapsed, m_elapsed);
+ SetTimeLabel(estimated, m_estimated);
+ SetTimeLabel(remaining, m_remaining);
+ }
+
+ if ( (value == m_maximum ) && !(GetWindowStyle() & wxPD_AUTO_HIDE) )
+ {
+ if ( m_btnAbort )
+ {
+ // tell the user what he should do...
+ m_btnAbort->SetLabel(_("Close"));
+ }
+
+ if ( !newmsg )
+ {
+ // also provide the finishing message if the application didn't
+ m_msg->SetLabel(_("Done."));
+ }
+
+ // so that we return TRUE below and that out [Cancel] handler knew what
+ // to do
+ m_state = Finished;
+
+ wxYield();
+
+ (void)ShowModal();
+ }
+ else
+ {
+ // update the display
+ wxYield();
+ }
#ifdef __WXMAC__
MacUpdateImmediately();
#endif
- return m_state != Canceled;
+ return m_state != Canceled;
}
// ----------------------------------------------------------------------------
void wxProgressDialog::OnClose(wxCloseEvent& event)
{
if ( m_state == Uncancelable )
+ {
+ // can't close this dialog
event.Veto(TRUE);
+ }
+ else if ( m_state == Finished )
+ {
+ // let the default handler close the window as we already terminated
+ event.Skip();
+ }
else
+ {
+ // next Update() will notice it
m_state = Canceled;
+ }
}
// ----------------------------------------------------------------------------
wxProgressDialog::~wxProgressDialog()
{
- if ( m_disableParentOnly )
+ if ( !(GetWindowStyle() & wxPD_APP_MODAL) )
{
- if ( m_parent )
- m_parent->Enable(TRUE);
+ if ( m_parentTop )
+ m_parentTop->Enable(TRUE);
}
else
{
// Empty implementation for now to keep the linker happy
wxString wxRegTipProvider::GetTip()
{
- return "";
+ return wxEmptyString;
}
#endif // __WIN32__
m_tipProvider = tipProvider;
// 1) create all controls in tab order
-
+
wxButton *btnClose = new wxButton(this, wxID_CANCEL, _("&Close"));
-
+
m_checkbox = new wxCheckBox(this, -1, _("&Show tips at startup"));
m_checkbox->SetValue(showAtStartup);
-
+
wxButton *btnNext = new wxButton(this, wxID_NEXT_TIP, _("&Next Tip"));
wxStaticText *text = new wxStaticText(this, -1, _("Did you know..."), wxDefaultPosition, wxSize(-1,30) );
m_text = new wxTextCtrl(this, -1, wxT(""),
wxDefaultPosition, wxSize(200, 160),
- wxTE_MULTILINE | wxTE_READONLY | wxSUNKEN_BORDER);
+ wxTE_MULTILINE |
+ wxTE_READONLY |
+ wxTE_RICH | // a hack to get rid of vert scrollbar
+ wxSUNKEN_BORDER);
#if defined(__WXMSW__)
m_text->SetFont(wxFont(12, wxROMAN, wxNORMAL, wxNORMAL));
#else
// 2) put them in boxes
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
-
+
wxBoxSizer *icon_text = new wxBoxSizer( wxHORIZONTAL );
icon_text->Add( bmp, 0, wxCENTER );
icon_text->Add( text, 1, wxCENTER | wxLEFT, 20 );
topsizer->Add( icon_text, 0, wxEXPAND | wxALL, 10 );
-
+
topsizer->Add( m_text, 1, wxEXPAND | wxLEFT|wxRIGHT, 10 );
wxBoxSizer *bottom = new wxBoxSizer( wxHORIZONTAL );
topsizer->Add( bottom, 0, wxEXPAND | wxALL, 10 );
SetTipText();
-
+
SetAutoLayout(TRUE);
SetSizer( topsizer );
-
+
topsizer->SetSizeHints( this );
topsizer->Fit( this );
// all modal dialogs currently shown
static wxWindowList wxModalDialogs;
+static wxWindow *m_oldFocus;
+
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
long style,
const wxString& name)
{
+ m_oldFocus = FindFocus();
+
SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
SetName(name);
wxTopLevelWindows.DeleteObject(this);
+ // this will call BringWindowToTop() if necessary to bring back our parent
+ // window to top
Show(FALSE);
- // VZ: this is bogus and breaks focus handling - it won't be returned to
- // the window which had it previosuly if we do this
-#if 0
- if (m_modalShowing)
- {
- // For some reason, wxWindows can activate another task altogether
- // when a frame is destroyed after a modal dialog has been invoked.
- // Try to bring the parent to the top.
- // dfgg: I moved this following line from end of function -
- // must not call if another window is on top!!
- // This can often happen with Close() and delayed deleting
- if (GetParent() && GetParent()->GetHWND())
- ::BringWindowToTop((HWND) GetParent()->GetHWND());
- }
-
- m_modalShowing = FALSE;
-#endif // 0
-
if ( !IsModal() )
wxModelessWindows.DeleteObject(this);
return (GetWindowStyleFlag() & wxDIALOG_MODAL) != 0;
}
-// VZ: this is the old version unchanged (reindented only), it will be removed
-// as soon as we're sure the new one works correctly
-#if 0
-
-bool wxDialog::Show(bool show)
-{
- m_isShown = show;
-
- if (show)
- InitDialog();
-
- bool modal = IsModal();
-
- if (modal)
- {
- if (show)
- {
- // find the top level window which had focus before - we will restore
- // focus to it later
- m_hwndOldFocus = 0;
- for ( HWND hwnd = ::GetFocus(); hwnd; hwnd = ::GetParent(hwnd) )
- {
- m_hwndOldFocus = (WXHWND)hwnd;
- }
-
- if (m_modalShowing)
- {
- BringWindowToTop((HWND) GetHWND());
- return TRUE;
- }
-
- m_modalShowing = TRUE;
- wxNode *node = wxModalDialogs.First();
- while (node)
- {
- wxDialog *box = (wxDialog *)node->Data();
- if (box != this)
- ::EnableWindow((HWND) box->GetHWND(), FALSE);
- node = node->Next();
- }
-
- // if we don't do it, some window might be deleted while we have pointers
- // to them in our disabledWindows list and the program will crash when it
- // will try to reenable them after the modal dialog end
- wxTheApp->DeletePendingObjects();
- wxList disabledWindows;
-
- node = wxModelessWindows.First();
- while (node)
- {
- wxWindow *win = (wxWindow *)node->Data();
- if (::IsWindowEnabled((HWND) win->GetHWND()))
- {
- ::EnableWindow((HWND) win->GetHWND(), FALSE);
- disabledWindows.Append(win);
- }
- node = node->Next();
- }
-
- ShowWindow((HWND) GetHWND(), SW_SHOW);
- EnableWindow((HWND) GetHWND(), TRUE);
- BringWindowToTop((HWND) GetHWND());
-
- if ( !wxModalDialogs.Find(this) )
- wxModalDialogs.Append(this);
-
- MSG msg;
- // Must test whether this dialog still exists: we may not process
- // a message before the deletion.
- while (wxModalDialogs.Find(this) && m_modalShowing && GetMessage(&msg, NULL, 0, 0))
- {
- if ( m_acceleratorTable.Ok() &&
- ::TranslateAccelerator((HWND)GetHWND(),
- (HACCEL)m_acceleratorTable.GetHACCEL(),
- &msg) )
- {
- // Have processed the message
- }
- else if ( !wxTheApp->ProcessMessage((WXMSG *)&msg) )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- // If we get crashes (as per George Tasker's message) with nested modal dialogs,
- // we should try removing the m_modalShowing test
-
- if (m_modalShowing && !::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
- // dfgg: NB MUST test m_modalShowing again as the message loop could have triggered
- // a Show(FALSE) in the mean time!!!
- // Without the test, we might delete the dialog before the end of modal showing.
- {
- while (wxTheApp->ProcessIdle() && m_modalShowing)
- {
- // Keep going until we decide we've done enough
- }
- }
- }
- // dfgg: now must specifically re-enable all other app windows that we disabled earlier
- node=disabledWindows.First();
- while(node) {
- wxWindow* win = (wxWindow*) node->Data();
- if (wxModalDialogs.Find(win) || wxModelessWindows.Find(win))
- {
- HWND hWnd = (HWND) win->GetHWND();
- if (::IsWindow(hWnd))
- ::EnableWindow(hWnd,TRUE);
- }
- node=node->Next();
- }
- }
- else // !show
- {
- ::SetFocus((HWND)m_hwndOldFocus);
-
- wxModalDialogs.DeleteObject(this);
-
- wxNode *last = wxModalDialogs.Last();
-
- // If there's still a modal dialog active, we
- // enable it, else we enable all modeless windows
- if (last)
- {
- // VZ: I don't understand what this is supposed to do, so I'll leave
- // it out for now and look for horrible consequences
- wxDialog *box = (wxDialog *)last->Data();
- HWND hwnd = (HWND) box->GetHWND();
-#if 0
- if (box->IsUserEnabled())
-#endif // 0
- EnableWindow(hwnd, TRUE);
- BringWindowToTop(hwnd);
- }
- else
- {
- wxNode *node = wxModelessWindows.First();
- while (node)
- {
- wxWindow *win = (wxWindow *)node->Data();
- HWND hwnd = (HWND) win->GetHWND();
- // Only enable again if not user-disabled.
-#if 0
- if (win->IsUserEnabled())
-#endif // 0
- EnableWindow(hwnd, TRUE);
- node = node->Next();
- }
- }
- // Try to highlight the correct window (the parent)
- HWND hWndParent = 0;
- if (GetParent())
- {
- hWndParent = (HWND) GetParent()->GetHWND();
- if (hWndParent)
- ::BringWindowToTop(hWndParent);
- }
- ShowWindow((HWND) GetHWND(), SW_HIDE);
- m_modalShowing = FALSE;
- }
- }
- else // !modal
- {
- if (show)
- {
- ShowWindow((HWND) GetHWND(), SW_SHOW);
- BringWindowToTop((HWND) GetHWND());
- }
- else
- {
- // Try to highlight the correct window (the parent)
- HWND hWndParent = 0;
- if (GetParent())
- {
- hWndParent = (HWND) GetParent()->GetHWND();
- if (hWndParent)
- ::BringWindowToTop(hWndParent);
- }
-
- if ( m_hWnd )
- ShowWindow((HWND) GetHWND(), SW_HIDE);
- }
- }
-
- return TRUE;
-}
-
-#else // 1
-
bool wxDialog::IsModalShowing() const
{
return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
wxWindow *parent = GetParent();
// remember where the focus was
- wxWindow *winFocus = FindFocus();
- if ( !winFocus )
+ if ( !m_oldFocus )
{
- winFocus = parent;
+ m_oldFocus = parent;
}
- if ( !winFocus )
+ if ( !m_oldFocus )
{
- winFocus = wxTheApp->GetTopWindow();
+ m_oldFocus = wxTheApp->GetTopWindow();
}
// disable the parent window first
}
// and restore focus
- if ( winFocus && (winFocus != this) )
+ if ( m_oldFocus && (m_oldFocus != this) )
{
- winFocus->SetFocus();
+ m_oldFocus->SetFocus();
}
}
bool wxDialog::Show(bool show)
{
- // The following is required when the parent has been disabled,
- // (modal dialogs, or modeless dialogs with disabling such as wxProgressDialog).
- // Otherwise the parent disappears behind other windows when the dialog is hidden.
- if (!show)
+ // The following is required when the parent has been disabled, (modal
+ // dialogs, or modeless dialogs with disabling such as wxProgressDialog).
+ // Otherwise the parent disappears behind other windows when the dialog is
+ // hidden.
+ if ( !show )
{
- HWND hwndParent = GetParent() ? (HWND) GetParent()->GetHWND() : (HWND)NULL;
- if ( hwndParent )
+ wxWindow *parent = GetParent();
+ if ( parent )
{
- ::BringWindowToTop(hwndParent);
+ ::BringWindowToTop(GetHwndOf(parent));
}
}
- if ( !wxDialogBase::Show(show) )
+ // ShowModal() may be called for already shown dialog
+ if ( !wxDialogBase::Show(show) && !(show && IsModal()) )
{
// nothing to do
return FALSE;
return TRUE;
}
-#endif // 0/1
-
// Replacement for Show(TRUE) for modal dialogs - returns return code
int wxDialog::ShowModal()
{
// message - otherwise it would close us
processed = !Close();
break;
+
+ case WM_SETCURSOR:
+ // we want to override the busy cursor for modal dialogs:
+ // typically, wxBeginBusyCursor() is called and then a modal dialog
+ // is shown, but the modal dialog shouldn't have this cursor
+ if ( wxIsBusy() )
+ {
+ rc = TRUE;
+
+ processed = TRUE;
+ }
}
if ( !processed )