From 1606f517d33c3f81392efac453e00bd8de985f87 Mon Sep 17 00:00:00 2001 From: guy Date: Thu, 24 Dec 2009 11:41:33 +0000 Subject: [PATCH] Patch level : 10.0 Files correlati : ba0 Ricompilazione Demo : [ ] Commento : Aggiunto supporto per disabilitazione nodi git-svn-id: svn://10.65.10.50/trunk@19843 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- xvaga/agasys.cpp | 284 ++++++++++++++++++++++++++++++++++++++++++++++- xvaga/xvt.h | 8 +- xvaga/xvtctl.cpp | 21 +++- 3 files changed, 303 insertions(+), 10 deletions(-) diff --git a/xvaga/agasys.cpp b/xvaga/agasys.cpp index e35e7aadc..fe62db611 100755 --- a/xvaga/agasys.cpp +++ b/xvaga/agasys.cpp @@ -237,11 +237,283 @@ bool aga_dde_terminate(unsigned long connection) return ok; } -BOOLEAN xvt_sys_multithread(MULTITHREAD_CALLBACK callback, void* out, const void* in, const void* param, - int tot, BOOLEAN WXUNUSED(progind)) +/////////////////////////////////////////////////////////// +// TProgressIndicator +/////////////////////////////////////////////////////////// + +class TProgressIndicator : public wxDialog { - BOOLEAN ok = TRUE; - for (int i = 0; i < tot && ok; i++) - ok = callback(out, in, param, i, tot); - return ok; + enum { MAX_GAUGES = 16 }; + wxGauge* m_pGauge[MAX_GAUGES]; + wxStaticText* m_pPassed; + wxStaticText* m_pResidual; + wxStaticText* m_pEstimated; + wxStopWatch m_chrono; + long m_nNextUpdate; + +protected: + DECLARE_EVENT_TABLE(); + + void Init(wxString msg, int nGauges, bool bCancellable); + wxString msec2str(long ms) const; + long Elapsed() const { return m_chrono.Time(); } + +public: + void SetRange(int nRange, int nGauge = 0); + bool SetProgress(int nPos, int nGauge = 0); + void SetMessage(wxString msg); + + TProgressIndicator(wxString msg, bool bCancellable, int nGauges); + TProgressIndicator(size_t nRange, wxString msg, bool bCancellable); + virtual ~TProgressIndicator(); +}; + +BEGIN_EVENT_TABLE(TProgressIndicator, wxDialog) +// EVT_MENU(wxID_CANCEL, TProgressIndicator::OnCancel) +END_EVENT_TABLE() + +wxString TProgressIndicator::msec2str(long ms) const +{ + int s = ms/1000; + const int h = s / 3600; + s -= h*3600; + const int m = s / 60; + s -= m*60; + return wxString::Format(wxT("%02d:%02d:%02d"), h, m, s); +} + +void TProgressIndicator::SetRange(int nRange, int nGauge) +{ + wxASSERT(nRange >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); + m_pGauge[nGauge]->SetRange(nRange); +} + +bool TProgressIndicator::SetProgress(int nPos, int nGauge) +{ + if (!IsShown()) + return false; + + wxASSERT(nPos >= 0 && nGauge >= 0 && nGauge < MAX_GAUGES); + m_pGauge[nGauge]->SetValue(nPos); + + const long elap = Elapsed(); + if (elap > m_nNextUpdate) + { + m_nNextUpdate = elap+CLOCKS_PER_SEC; + m_pPassed->SetLabel(msec2str(elap)); + + wxLongLong_t nTotValue = 0, nTotRange = 0; + for (int i = 0; i < MAX_GAUGES && m_pGauge[i]; i++) + { + const int nValue = m_pGauge[i]->GetValue(); + const int nRange = m_pGauge[i]->GetRange(); + if (nValue < nRange) // Escludi dal calcolo i processi già terminati + { + nTotValue += nValue; + nTotRange += nRange; + } + } + if (nTotValue > 0) + { + const long est = long(elap * nTotRange / nTotValue); + m_pEstimated->SetLabel(msec2str(est)); + m_pResidual->SetLabel(msec2str(est-elap)); + } + + wxYield(); + } + + return true; +} + +void TProgressIndicator::SetMessage(wxString msg) +{ SetLabel(msg); } + +void TProgressIndicator::Init(wxString msg, int nGauges, bool bCancellable) +{ + const int nGap = 4; + wxBoxSizer* pTopSizer = new wxBoxSizer(wxVERTICAL); + SetSizer(pTopSizer); + + memset(m_pGauge, 0, sizeof(m_pGauge)); + for (int i = 0; i < nGauges; i++) + { + m_pGauge[i] = new wxGauge(this, 1001+i, 100, wxDefaultPosition, wxSize(400, -1)); + pTopSizer->Add(m_pGauge[i], 0, wxALL, nGap); + } + + wxGridSizer* pTimersSizer = new wxGridSizer(1, 3, nGap, nGap); + pTopSizer->Add(pTimersSizer, 0, wxEXPAND); + + wxStaticBoxSizer* pPassed = new wxStaticBoxSizer(wxVERTICAL, this, _("Elapsed Time")); + pTimersSizer->Add(pPassed, 0, wxEXPAND); + m_pPassed = new wxStaticText(this, 1101, wxT("00:00:00")); + pPassed->Add(m_pPassed, 0, wxALL|wxALIGN_CENTER, 0); + + wxStaticBoxSizer* pResidual = new wxStaticBoxSizer(wxVERTICAL, this, _("Residual Time")); + pTimersSizer->Add(pResidual, 0, wxEXPAND); + m_pResidual = new wxStaticText(this, 1102, wxT("00:00:00")); + pResidual->Add(m_pResidual, 0, wxALL|wxALIGN_CENTER, 0); + + wxStaticBoxSizer* pEstimated = new wxStaticBoxSizer(wxVERTICAL, this, _("Estimated Time")); + pTimersSizer->Add(pEstimated, 0, wxEXPAND); + m_pEstimated = new wxStaticText(this, 1103, wxT("00:00:00")); + pEstimated->Add(m_pEstimated, 0, wxALL|wxALIGN_CENTER, 0); + + wxButton* pCancel = NULL; + if (bCancellable) + { + pCancel = new wxButton(this, wxID_CANCEL, _("Cancel")); + pTopSizer->Add(pCancel, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, nGap); + } + + pTopSizer->SetSizeHints(this); + + SetMessage(msg); + + Show(); + Enable(); + Update(); + + m_nNextUpdate = 0; + m_chrono.Start(); +} + +TProgressIndicator::TProgressIndicator(size_t nRange, wxString msg, bool bCancellable) + : wxDialog(NULL, wxID_ANY, msg) +{ + Init(msg, 1, bCancellable); + SetRange(nRange, 0); +} + +TProgressIndicator::TProgressIndicator(wxString msg, bool bCancellable, int nGauges) + : wxDialog(NULL, wxID_ANY, msg) +{ + Init(msg, nGauges, bCancellable); +} + +TProgressIndicator::~TProgressIndicator() +{ } + +/////////////////////////////////////////////////////////// +// Multiprocess +/////////////////////////////////////////////////////////// + +class TWorker : public wxThread +{ + XVT_MULTITHREAD_CALLBACK m_pFunc; + void* m_pCaller; + void* m_pData; + int m_nFirst, m_nLast, m_nTotal; + TProgressIndicator* m_pi; + int m_nGauge; + +protected: + virtual ExitCode Entry(); + +public: + TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, + int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge); +}; + +wxThread::ExitCode TWorker::Entry() +{ + ExitCode ec = 0; + if (m_pi != NULL) + { + m_pi->SetRange(m_nLast-m_nFirst, m_nGauge); + for (int i = m_nFirst; i < m_nLast && ec == 0; i++) + { + ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); + if (!m_pi->SetProgress(i-m_nFirst+1, m_nGauge)) + ec = ExitCode(-1); + } + } + else + { + for (int i = m_nFirst; i < m_nLast && ec == 0; i++) + ec = (ExitCode)m_pFunc(m_pCaller, m_pData, i, m_nTotal); + } + return ec; +} + +TWorker::TWorker(XVT_MULTITHREAD_CALLBACK func, void* pCaller, void* pData, + int nFirst, int nLast, int nTotal, TProgressIndicator* pi, int nGauge) + : wxThread(wxTHREAD_JOINABLE), m_pFunc(func), m_pCaller(pCaller), m_pData(pData), + m_nFirst(nFirst), m_nLast(nLast), m_nTotal(nTotal), m_pi(pi), m_nGauge(nGauge) + +{ +// SetPriority(WXTHREAD_MIN_PRIORITY); + Create(); +} + +BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* pData, + int tot, const char* msg) +{ + const int MAX_WORKERS = 16; + + // Bilanciamento automatico + int nWorkers = wxThread::GetCPUCount(); + if (nWorkers <= 0) + nWorkers = 1; + if (nWorkers > tot) + nWorkers = tot; + if (nWorkers > MAX_WORKERS) + nWorkers = MAX_WORKERS; + + int ret = 0; + if (nWorkers > 1) + { + TProgressIndicator* pi = NULL; + if (msg && *msg) + pi = new TProgressIndicator(msg, tot > nWorkers, nWorkers); + + TWorker* worker[MAX_WORKERS]; memset(worker, 0, sizeof(worker)); + + int nFirst, nLast = 0, w; + for (w = 0; w < nWorkers; w++) + { + nFirst = nLast; + nLast = tot*(w+1)/nWorkers; + worker[w] = new TWorker(pFunc, pCaller, pData, nFirst, nLast, tot, pi, w); + } + + for (w = 0; w < nWorkers; w++) + worker[w]->Run(); + + if (pi != NULL) + pi->Refresh(); + + for (w = 0; w < nWorkers; w++) + { + const wxThread::ExitCode r = worker[w]->Wait(); + if (ret == 0 && r != 0) + ret = int(r); + delete worker[w]; + worker[w] = NULL; + } + + if (pi != NULL) + delete pi; + } + else + { + if (msg && *msg) + { + TProgressIndicator pi(size_t(tot), msg, tot > nWorkers); + for (int i = 0; i < tot && ret == 0; i++) + { + ret = pFunc(pCaller, pData, i, tot); + if (!pi.SetProgress(i+1)) + ret = -1; + } + } + else + { + for (int i = 0; i < tot && ret == 0; i++) + ret = pFunc(pCaller, pData, i, tot); + } + } + + return ret; } diff --git a/xvaga/xvt.h b/xvaga/xvt.h index a189f0fdd..21614b764 100755 --- a/xvaga/xvt.h +++ b/xvaga/xvt.h @@ -224,7 +224,7 @@ XVTDLL void xvt_image_set_ncolors(XVT_IMAGE image, short ncolors); XVTDLL void xvt_image_set_pixel(XVT_IMAGE image, short x, short y, COLOR color); XVTDLL void xvt_image_transfer(XVT_IMAGE dstimage, XVT_IMAGE srcimage, RCT *dstrctp, RCT *srcrctp); -typedef void (*IMAGE_FILTER)(short x, short y, unsigned char* rgba, void* jolly); +typedef XVT_CALLCONV_TYPEDEF(void, IMAGE_FILTER, (short x, short y, unsigned char* rgba, void* jolly)); XVTDLL BOOLEAN xvt_image_filter(XVT_IMAGE image, IMAGE_FILTER filter, void* param); XVTDLL int xvt_list_add_item(WINDOW win, short icon, const char* text, int flags); @@ -362,6 +362,7 @@ XVTDLL WINDOW xvt_treeview_create(WINDOW parent_win, XVT_IMAGE item_image, XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image, long attrs, int line_height); XVTDLL void xvt_treeview_destroy_node(WINDOW win, XVT_TREEVIEW_NODE node); +XVTDLL BOOLEAN xvt_treeview_enable_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN on); XVTDLL BOOLEAN xvt_treeview_expand_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN recurse); XVTDLL XVT_TREEVIEW_NODE xvt_treeview_find_node_string(WINDOW win, const char* text); XVTDLL XVT_TREEVIEW_NODE xvt_treeview_get_child_node(WINDOW win, XVT_TREEVIEW_NODE parent_node, int position); @@ -387,8 +388,9 @@ XVTDLL long xvt_sys_execute(const char* cmdline, BOOLEAN sync, BOOLEAN iconi XVTDLL long xvt_sys_execute_in_window(const char* cmdline, WINDOW win); XVTDLL long xvt_sys_close_children(WINDOW win); XVTDLL long xvt_sys_close_siblings(WINDOW win); -typedef BOOLEAN MULTITHREAD_CALLBACK(void* output, const void* input, const void* params, size_t i, size_t total); -XVTDLL BOOLEAN xvt_sys_multithread(MULTITHREAD_CALLBACK callback, void* out, const void* in, const void* param, size_t tot, BOOLEAN progind); + +typedef XVT_CALLCONV_TYPEDEF(int, XVT_MULTITHREAD_CALLBACK, (void* pCaller, void* pData, int i, int tot) ); +XVTDLL BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK callback, void* pCaller, void* pData, int tot, const char* msg); XVTDLL BOOLEAN xvt_sys_get_host_name(char* name, int maxlen); XVTDLL BOOLEAN xvt_sys_get_user_name(char* name, int maxlen); diff --git a/xvaga/xvtctl.cpp b/xvaga/xvtctl.cpp index 84b354d87..166cb6b3f 100755 --- a/xvaga/xvtctl.cpp +++ b/xvaga/xvtctl.cpp @@ -107,7 +107,7 @@ class TwxTreeCtrl : public wxTreeCtrl { WX_DECLARE_VOIDPTR_HASH_MAP(int, XVT_IMAGE_Map); XVT_IMAGE_Map m_img; - wxColour m_clrSelFore, m_clrSelBack; + wxColour m_clrSelFore, m_clrSelBack, m_clrDisFore; int m_nFrozen; private: @@ -131,6 +131,7 @@ public: void SetColors(const XVT_COLOR_COMPONENT* colors); void Suspend(); void Resume(); + void Enable(const wxTreeItemId& id, bool on); TwxTreeCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size); }; @@ -1126,6 +1127,11 @@ void TwxTreeCtrl::SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image, } } +void TwxTreeCtrl::Enable(const wxTreeItemId& id, bool on) +{ + SetItemTextColour(id, on ? m_clrSelFore : m_clrDisFore); +} + void TwxTreeCtrl::Suspend() { m_nFrozen++; } @@ -1147,6 +1153,7 @@ void TwxTreeCtrl::SetColors(const XVT_COLOR_COMPONENT* colors) case XVT_COLOR_FOREGROUND: SetOwnForegroundColour(rgb); break; case XVT_COLOR_HIGHLIGHT : m_clrSelBack = rgb; break; case XVT_COLOR_SELECT : m_clrSelFore = rgb; break; + case XVT_COLOR_TROUGH : m_clrDisFore = rgb; break; default : break; } } @@ -1251,6 +1258,18 @@ void xvt_treeview_destroy_node(WINDOW win, XVT_TREEVIEW_NODE node) } } +BOOLEAN xvt_treeview_enable_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN on) +{ + BOOLEAN ok = (win != NULL_WIN) && (node != NULL); + if (ok) + { + CAST_TREEVIEW(win, tv); + wxTreeItemId id(node); + tv.Enable(id, on != FALSE); + } + return ok; +} + BOOLEAN xvt_treeview_expand_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN recurse) { BOOLEAN ok = (win != NULL_WIN) && (node != NULL);