From: Vadim Zeitlin Date: Sat, 29 Jan 2000 02:34:46 +0000 (+0000) Subject: 1. thread sample now uses wxProgressDialog for more "realism" X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/b9de131510fd94cefe27b0c6c26ce33c729c81fa?ds=sidebyside 1. thread sample now uses wxProgressDialog for more "realism" 2. added a filled rect with outline to the drawing sample and changed DrawLine() to show how MSW draws them git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5729 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index 033c391e33..3b788186a5 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -254,7 +254,7 @@ bool MyApp::LoadImages() if ( !path ) return FALSE; gs_bmpMask.LoadFile(path, wxBITMAP_TYPE_BMP); - + // This is so wrong, it hurts. // gs_bmpMask.SetDepth(1); // wxMask *mask = new wxMask(gs_bmpMask); @@ -573,45 +573,54 @@ void MyCanvas::DrawDefault(wxDC& dc) dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle( 0, 100, 1000, 300 ); - // test the rectangle outline drawing - there should be one pixel between + // test the rectangle outline drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxWHITE_PEN); dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.DrawRectangle(100, 170, 49, 29); dc.DrawRectangle(150, 170, 49, 29); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(200, 160, 200, 210); - dc.DrawLine(100, 200, 210, 200); - - // test the rectangle filled drawing - there should be one pixel between + dc.DrawLine(200, 210, 200, 170); + dc.DrawLine(210, 200, 100, 200); + + // test the rectangle filled drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush( *wxWHITE_BRUSH ); dc.DrawRectangle(300, 170, 49, 29); dc.DrawRectangle(350, 170, 49, 29); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(400, 160, 400, 210); - dc.DrawLine(300, 200, 410, 200); - - // test the rectangle outline drawing - there should be one pixel between + dc.DrawLine(400, 170, 400, 210); + dc.DrawLine(300, 200, 410, 200); + + // and now for filled rect with outline + dc.SetPen(*wxRED_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(500, 170, 49, 29); + dc.DrawRectangle(550, 170, 49, 29); + dc.SetPen(*wxWHITE_PEN); + dc.DrawLine(600, 170, 600, 210); + dc.DrawLine(500, 200, 610, 200); + + // test the rectangle outline drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxWHITE_PEN); dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.DrawRoundedRectangle(100, 270, 49, 29, 6); dc.DrawRoundedRectangle(150, 270, 49, 29, 6); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(200, 260, 200, 310); - dc.DrawLine(100, 300, 210, 300); - - // test the rectangle filled drawing - there should be one pixel between + dc.DrawLine(200, 270, 200, 310); + dc.DrawLine(100, 300, 210, 300); + + // test the rectangle filled drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush( *wxWHITE_BRUSH ); dc.DrawRoundedRectangle(300, 270, 49, 29, 6); dc.DrawRoundedRectangle(350, 270, 49, 29, 6); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(400, 260, 400, 310); - dc.DrawLine(300, 300, 410, 300); + dc.DrawLine(400, 270, 400, 310); + dc.DrawLine(300, 300, 410, 300); } diff --git a/samples/thread/test.cpp b/samples/thread/test.cpp index 5788b0caa2..e7b4069ac0 100644 --- a/samples/thread/test.cpp +++ b/samples/thread/test.cpp @@ -38,6 +38,8 @@ #include "wx/dynarray.h" #include "wx/time.h" +#include "wx/progdlg.h" + class MyThread; WX_DEFINE_ARRAY(wxThread *, wxArrayThread); @@ -69,6 +71,9 @@ public: // operations void WriteText(const wxString& text) { m_txtctrl->WriteText(text); } + // accessors for MyWorkerThread (called in its context!) + bool Cancelled(); + // callbacks void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -79,9 +84,10 @@ public: void OnStopThread(wxCommandEvent& event); void OnPauseThread(wxCommandEvent& event); void OnResumeThread(wxCommandEvent& event); - + void OnStartWorker(wxCommandEvent& event); void OnWorkerEvent(wxCommandEvent& event); + void OnUpdateWorker(wxUpdateUIEvent& event); void OnIdle(wxIdleEvent &event); @@ -95,6 +101,15 @@ private: // remember the number of running threads and total number of threads size_t m_nRunning, m_nCount; + // the progress dialog which we show while worker thread is running + wxProgressDialog *m_dlgProgress; + + // was the worker thread cancelled by user? + bool m_cancelled; + + // protects m_cancelled + wxCriticalSection m_critsectWork; + DECLARE_EVENT_TABLE() }; @@ -156,7 +171,7 @@ void MyThread::WriteText(const wxString& text) msg << text; m_frame->WriteText(msg); - + wxMutexGuiLeave(); } @@ -228,30 +243,34 @@ void MyWorkerThread::OnExit() void *MyWorkerThread::Entry() { - for ( m_count = 0; m_count < 10; m_count++ ) + for ( m_count = 0; !m_frame->Cancelled() && (m_count < 100); m_count++ ) { // check if we were asked to exit if ( TestDestroy() ) break; - + wxString text; text.Printf("[%u] Thread 0x%x here!!", m_count, GetId()); - // create any type of command event here + // create any type of command event here wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT ); - event.SetInt( WORKER_EVENT ); + event.SetInt( m_count ); event.SetString( text ); - + // send in a thread-safe way wxPostEvent( m_frame, event ); - + // same as: // m_frame->AddPendingEvent( event ); // wxSleep() can't be called from non-main thread! - wxThread::Sleep(1000); + wxThread::Sleep(200); } + wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT ); + event.SetInt(-1); // that's all + wxPostEvent( m_frame, event ); + return NULL; } @@ -268,7 +287,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread) EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread) EVT_MENU(TEST_RESUME_THREAD, MyFrame::OnResumeThread) - + + EVT_UPDATE_UI(TEST_START_WORKER, MyFrame::OnUpdateWorker) EVT_MENU(TEST_START_WORKER, MyFrame::OnStartWorker) EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent) @@ -302,7 +322,7 @@ bool MyApp::OnInit() thread_menu->Append(TEST_RESUME_THREAD, "&Resume suspended thread\tCtrl-R"); thread_menu->AppendSeparator(); thread_menu->Append(TEST_START_WORKER, "Start &worker thread\tCtrl-W"); - + menu_bar->Append(thread_menu, "&Thread"); frame->SetMenuBar(menu_bar); @@ -321,6 +341,8 @@ MyFrame::MyFrame(wxFrame *frame, const wxString& title, { m_nRunning = m_nCount = 0; + m_dlgProgress = (wxProgressDialog *)NULL; + CreateStatusBar(2); m_txtctrl = new wxTextCtrl(this, -1, "", wxPoint(0, 0), wxSize(0, 0), @@ -517,6 +539,11 @@ void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event)) m_txtctrl->Clear(); } +void MyFrame::OnUpdateWorker(wxUpdateUIEvent& event) +{ + event.Enable( m_dlgProgress == NULL ); +} + void MyFrame::OnStartWorker(wxCommandEvent& WXUNUSED(event)) { MyWorkerThread *thread = new MyWorkerThread(this); @@ -525,14 +552,59 @@ void MyFrame::OnStartWorker(wxCommandEvent& WXUNUSED(event)) { wxLogError("Can't create thread!"); } - + + m_dlgProgress = new wxProgressDialog + ( + "Progress dialog", + "Wait until the thread terminates or press [Cancel]", + 100, + this, + wxPD_CAN_ABORT | + wxPD_APP_MODAL | + wxPD_ELAPSED_TIME | + wxPD_ESTIMATED_TIME | + wxPD_REMAINING_TIME + ); + + // thread is not running yet, no need for crit sect + m_cancelled = FALSE; + thread->Run(); } void MyFrame::OnWorkerEvent(wxCommandEvent& event) { +#if 0 WriteText( "Got message from worker thread: " ); WriteText( event.GetString() ); WriteText( "\n" ); +#else + int n = event.GetInt(); + if ( n == -1 ) + { + m_dlgProgress->Destroy(); + m_dlgProgress = (wxProgressDialog *)NULL; + + // the dialog is aborted because the event came from another thread, so + // we may need to wake up the main event loop for the dialog to be + // really closed + wxWakeUpIdle(); + } + else + { + if ( !m_dlgProgress->Update(n) ) + { + wxCriticalSectionLocker lock(m_critsectWork); + + m_cancelled = TRUE; + } + } +#endif } +bool MyFrame::Cancelled() +{ + wxCriticalSectionLocker lock(m_critsectWork); + + return m_cancelled; +}