- Pause slide show for workunits that are not running

- Add message to space below slide show images to explain status of the workunit (running, paused)
		- Fixed bug that sometimes caused slide shows to not load properly when first downloaded
		  or after they have been updated by the project
		- Prevent workunit name from overflowing the side of BSG
		- Play with tabs to make the selected tab stand out
		- Fixed bug which caused a crash when switching between simple and advanced views
		- Fixed a significant memory leak
		- Eliminate some compiler warnings

svn path=/trunk/boinc/; revision=11274
This commit is contained in:
Kevin Reed 2006-10-12 02:18:08 +00:00
parent c539882513
commit 98b1cf8d7d
12 changed files with 163 additions and 82 deletions

View File

@ -11018,3 +11018,26 @@ David 11 Oct 2006
http_curl.C
sched/
trickle_handler.C
Kevin 11 Oct 2006
- BSG
- Pause slide show for workunits that are not running
- Add message to space below slide show images to explain status of the workunit (running, paused)
- Fixed bug that sometimes caused slide shows to not load properly when first downloaded
or after they have been updated by the project
- Prevent workunit name from overflowing the side of BSG
- Play with tabs to make the selected tab stand out
- Fixed bug which caused a crash when switching between simple and advanced views
- Fixed a significant memory leak
- Eliminate some compiler warnings
clientgui/
sg_BoincSimpleGUI.cpp/h
sg_ClientStateIndicator.cpp
sg_ImageButton.cpp/h
sg_ProjectsComponent.cpp
sg_SGUIListControl.cpp/h
sg_StatImageLoader.cpp
sg_ViewTabPage.cpp/h

View File

@ -70,7 +70,6 @@ CSimpleFrame::CSimpleFrame(wxString title, wxIcon* icon) :
wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN | wxNO_FULL_REPAINT_ON_RESIZE)
{
wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Overloaded Constructor Function Begin"));
RestoreState();
// Initialize Application
@ -98,7 +97,6 @@ CSimpleFrame::CSimpleFrame(wxString title, wxIcon* icon) :
CSimpleFrame::~CSimpleFrame()
{
wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::CSimpleFrame - Destructor Function Begin"));
wxASSERT(m_pFrameRenderTimer);
SaveState();
@ -284,7 +282,8 @@ void CSimpleFrame::OnFrameRender(wxTimerEvent& WXUNUSED(event)) {
CMainDocument* pDoc = wxGetApp().GetDocument();
if (!projectViewInitialized) {
InitProjectView();
InitProjectView();
return;
} else if ( pDoc->IsConnected() ) {
UpdateProjectView();
}
@ -399,8 +398,7 @@ void CSimpleFrame::ReskinAppGUI(){
wxLogTrace(wxT("Function Start/End"), wxT("CSimpleFrame::ReskinAppGUI - Function End"));
}
void CSimpleFrame::OnBtnClick(wxCommandEvent& event){ //init function
wxObject *m_wxBtnObj = event.GetEventObject();
void CSimpleFrame::OnBtnClick(wxCommandEvent& WXUNUSED(event)){ //init function
}
//end function
void CSimpleFrame::OnPageChanged(wxFlatNotebookEvent& WXUNUSED(event))

View File

@ -54,17 +54,12 @@ ClientStateIndicator::ClientStateIndicator(CSimpleFrame* parent,wxPoint coord) :
appSkin = SkinClass::Instance();
CreateComponent();
error_time = 0;
m_connRenderTimer = new wxTimer(this, ID_ANIMATIONRENDERTIMER);
}
ClientStateIndicator::~ClientStateIndicator()
{
if (m_connRenderTimer) {
if ( clientState == CLIENT_STATE_ACTION ) {
m_connRenderTimer->Stop();
delete m_connRenderTimer;
}
}
delete m_connRenderTimer;
}
void ClientStateIndicator::CreateComponent(){
@ -94,7 +89,6 @@ void ClientStateIndicator::SetActionState(const char* message)
m_connIndV.push_back(i_connInd);
}
//set animation timer for interface
m_connRenderTimer = new wxTimer(this, ID_ANIMATIONRENDERTIMER);
wxASSERT(m_connRenderTimer);
m_connRenderTimer->Start(500);
}

View File

@ -31,24 +31,27 @@ BEGIN_EVENT_TABLE(CImageButton, wxPanel)
EVT_ERASE_BACKGROUND(CImageButton::OnEraseBackground)
END_EVENT_TABLE()
CImageButton::CImageButton(wxWindow* parent,wxBitmap bg, wxPoint coord,wxSize size,bool drawText = false) : wxPanel(parent, wxID_ANY, coord, size, wxNO_BORDER)
CImageButton::CImageButton(wxWindow* parent,wxBitmap bg, wxPoint coord,wxSize size,bool drawText, int initStatus) : wxPanel(parent, wxID_ANY, coord, size, wxNO_BORDER)
{
btnBG = bg;
m_drawText = drawText;
status = initStatus;
}
void CImageButton::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
if(m_drawText)
{
dc.SetTextForeground(wxColour(*wxWHITE));
dc.SetFont(wxFont(7,74,90,90,0,wxT("Arial")));
dc.SetTextForeground(wxColour(*wxWHITE));
dc.SetFont(wxFont(7,74,90,90,0,wxT("Arial")));
int x, y;
GetSize(&x,&y);
wxCoord width, height;
dc.GetTextExtent(GetStatusText(), &width, &height);
dc.DrawText(GetStatusText(), wxPoint(7, y-height-4));
// display show graphics text (if available)
if(m_drawText) {
wxString text = wxString(wxT("> Show graphics"));
wxCoord width, height;
dc.GetTextExtent(text, &width, &height);
int x, y;
GetSize(&x,&y);
dc.DrawText(text, wxPoint(x-width-7,y-height-4));
}
}
@ -56,6 +59,34 @@ void CImageButton::SetImage(wxBitmap bg)
{
btnBG = bg;
}
void CImageButton::SetStatus(int newStatus) {
status = newStatus;
}
int CImageButton::GetStatus() {
return status;
}
wxString CImageButton::GetStatusText() {
if ( status == TAB_STATUS_RUNNING ) {
return wxString(_T("Running"));
} else if ( status == TAB_STATUS_PREEMPTED ) {
return wxString(_T("Paused: Other work running"));
} else if ( status == TAB_STATUS_PAUSED_USER_REQ ) {
return wxString(_T("Paused: User initiatied"));
} else if ( status == TAB_STATUS_PAUSED_USER_ACTIVE ) {
return wxString(_T("Paused: User active"));
} else if ( status == TAB_STATUS_PAUSED_POWER ) {
return wxString(_T("Paused: Computer on battery"));
} else if ( status == TAB_STATUS_PAUSED_TIME_OF_DAY ) {
return wxString(_T("Paused: Time of Day"));
} else if ( status == TAB_STATUS_PAUSED_BENCHMARKS ) {
return wxString(_T("Paused: Benchmarks running"));
} else if ( status == TAB_STATUS_PAUSED ) {
return wxString(_T("Paused"));
} else {
return wxString("");
}
}
void CImageButton::OnEraseBackground(wxEraseEvent& event){
event.Skip(false);
@ -69,7 +100,7 @@ void CImageButton::OnEraseBackground(wxEraseEvent& event){
}
}
void CImageButton::OnLeftUp(wxMouseEvent& event)
void CImageButton::OnLeftUp(wxMouseEvent& WXUNUSED(event))
{
CViewTabPage* pView = wxDynamicCast(GetParent(), CViewTabPage);
wxASSERT(pView);

View File

@ -24,23 +24,34 @@
#pragma interface "sg_ImageButton.cpp"
#endif
#define TAB_STATUS_RUNNING 1
#define TAB_STATUS_PREEMPTED 2
#define TAB_STATUS_PAUSED_USER_ACTIVE 3
#define TAB_STATUS_PAUSED_USER_REQ 4
#define TAB_STATUS_PAUSED_POWER 5
#define TAB_STATUS_PAUSED_TIME_OF_DAY 6
#define TAB_STATUS_PAUSED_BENCHMARKS 7
#define TAB_STATUS_PAUSED 8
class CImageButton : public wxPanel
{
public:
/// Constructors
CImageButton(wxWindow* parent,wxBitmap bg,wxPoint coord, wxSize size, bool drawText);
CImageButton(wxWindow* parent,wxBitmap bg,wxPoint coord, wxSize size, bool drawText, int initStatus);
void SetImage(wxBitmap bg);
void OnPaint(wxPaintEvent& event);
void OnLeftUp(wxMouseEvent& event);
void OnEraseBackground(wxEraseEvent& event);
void SetShowText(bool show);
void SetStatus(int status);
int GetStatus();
private:
//static const int MaxWidth = 320;
//static const int MaxHeight = 240;
wxBitmap btnBG;
bool m_drawText;
int status;
wxString GetStatusText();
DECLARE_EVENT_TABLE()
};

View File

@ -520,6 +520,7 @@ void CProjectsComponent::OnBtnClick(wxCommandEvent& event){ //init function
wxASSERT(pDlg);
if ( pDlg->ShowModal() == wxID_OK ){
if(pDlg->GetSkinName() != pFrame->skinName){
GetParent()->Freeze();
if ( appSkin->change_skin(pDlg->GetSkinName()) ) {
pFrame->skinName = pDlg->GetSkinName();
pFrame->ReskinAppGUI();
@ -527,6 +528,7 @@ void CProjectsComponent::OnBtnClick(wxCommandEvent& event){ //init function
wxMessageBox("Incompatible skin. Skin will not be changed.");
pDlg->SetSkinName(pFrame->skinName);
}
GetParent()->Thaw();
}
}
pDlg->Destroy();

View File

@ -50,24 +50,6 @@ CSGUIListCtrl::CSGUIListCtrl(
}
CSGUIListCtrl::~CSGUIListCtrl()
{
}
bool CSGUIListCtrl::OnSaveState(wxConfigBase* pConfig) {
return true;
}
bool CSGUIListCtrl::OnRestoreState(wxConfigBase* pConfig) {
return true;
}
void CSGUIListCtrl::OnClick(wxCommandEvent& event) {
}

View File

@ -34,11 +34,6 @@ public:
CSGUIListCtrl();
CSGUIListCtrl(CDlgMessages* pView, wxWindowID iListWindowID, int iListWindowFlags);
~CSGUIListCtrl();
virtual bool OnSaveState(wxConfigBase* pConfig);
virtual bool OnRestoreState(wxConfigBase* pConfig);
private:
virtual void OnClick(wxCommandEvent& event);

View File

@ -26,14 +26,13 @@ END_EVENT_TABLE()
StatImageLoader::StatImageLoader(wxWindow* parent, std::string url) : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(40,40), wxNO_BORDER)
{
m_prjUrl = url;
attemptToReloadTimer = new wxTimer(this, ID_CHECKFORPROJECTICONDOWNLOADED);
CreateMenu();
}
StatImageLoader::~StatImageLoader() {
if ( attemptToReloadTimer <= NULL ) {
attemptToReloadTimer->Stop();
delete attemptToReloadTimer;
}
delete attemptToReloadTimer;
delete statPopUpMenu;
}
void StatImageLoader::PopUpMenu(wxMouseEvent& WXUNUSED(event))
@ -58,7 +57,6 @@ void StatImageLoader::CreateMenu()
PROJECT* project = pDoc->state.lookup_project(m_prjUrl);
urlCount = project->gui_urls.size();
statPopUpMenu = new wxMenu(wxSIMPLE_BORDER);
// Add the home page link
@ -192,7 +190,6 @@ void StatImageLoader::LoadImage(std::string project_icon, wxBitmap* defaultImage
if ( defaultUsed ) {
projectIcon = project_icon;
numReloadTries = 80; // check for 10 minutes
attemptToReloadTimer = new wxTimer(this, ID_CHECKFORPROJECTICONDOWNLOADED);
attemptToReloadTimer->Start(7500);
}
}

View File

@ -58,13 +58,10 @@ CViewTabPage::CViewTabPage(WorkunitNotebook* parent,RESULT* result,std::string n
appSkin = SkinClass::Instance();
//create page
CreatePage();
scheduler_rpc_in_progress = false;
scheduler_rpc_in_progress = 5; // defaut to true in case the slide show is loaded before all files are downloaded
}
CViewTabPage::~CViewTabPage() {
if ( wSlideShow <= NULL ) {
delete wSlideShow;
}
}
void CViewTabPage::CreatePage()
@ -83,8 +80,9 @@ void CViewTabPage::CreatePage()
//Line Proj Name
lnProjName = new CStaticLine(this,wxPoint(20,36),wxSize(316,1));
lnProjName->SetLineColor(appSkin->GetStaticLineCol());
//TODO - is this line below needed?
wxStaticLine* spacerLine = new wxStaticLine(this,-1,wxPoint(20,36),wxSize(305,1));
//Create with a two step process to eliminate compiler warning
wxStaticLine* spacerLine = new wxStaticLine();
spacerLine->Create(this,-1,wxPoint(20,36),wxSize(305,1));
//My Progress
wrkUnitName = wxString(resultWU->name.c_str(),wxConvUTF8);
@ -102,12 +100,36 @@ void CViewTabPage::CreatePage()
if (resultWU->supports_graphics) {
m_hasGraphic = true;
}
int status = ComputeState();
// project image behind graphic <><><>
btnAminBg = new CImageButton(this,*(appSkin->GetAnimationBg()),wxPoint(28,154),wxSize(294,146),m_hasGraphic);
btnAminBg = new CImageButton(this,*(appSkin->GetAnimationBg()),wxPoint(28,154),wxSize(294,146),m_hasGraphic, status);
CreateSlideShowWindow();
}
int CViewTabPage::ComputeState() {
int status = TAB_STATUS_PREEMPTED;
if ( resultWU->active_task_state == 1 ) {
status = TAB_STATUS_RUNNING;
} else {
CMainDocument* pDoc = wxGetApp().GetDocument();
CC_STATUS ccStatus;
pDoc->GetCoreClientStatus(ccStatus);
if ( ccStatus.task_suspend_reason & SUSPEND_REASON_BATTERIES ) {
status = TAB_STATUS_PAUSED_POWER;
} else if ( ccStatus.task_suspend_reason & SUSPEND_REASON_USER_ACTIVE ) {
status = TAB_STATUS_PAUSED_USER_ACTIVE;
} else if ( ccStatus.task_suspend_reason & SUSPEND_REASON_USER_REQ ) {
status = TAB_STATUS_PAUSED_USER_REQ;
} else if ( ccStatus.task_suspend_reason & SUSPEND_REASON_TIME_OF_DAY ) {
status = TAB_STATUS_PAUSED_TIME_OF_DAY;
} else if ( ccStatus.task_suspend_reason & SUSPEND_REASON_BENCHMARKS ) {
status = TAB_STATUS_PAUSED_BENCHMARKS;
}
}
return status;
}
void CViewTabPage::LoadSlideShow(std::vector<wxBitmap> *vSlideShow) {
char urlDirectory[256];
CMainDocument* pDoc = wxGetApp().GetDocument();
@ -182,10 +204,14 @@ void CViewTabPage::UpdateInterface()
CMainDocument* pDoc = wxGetApp().GetDocument();
PROJECT* project = pDoc->state.lookup_project(resultWU->project_url);
if ( project > NULL && project->scheduler_rpc_in_progress ) {
scheduler_rpc_in_progress = true;
// wait a few seconds before reloading in case there is a delay between
// the project update and the slide show being available
scheduler_rpc_in_progress = 10;
} else if ( scheduler_rpc_in_progress && !Downloading() ) {
scheduler_rpc_in_progress = false;
GetCanvas()->ReloadSlideShow(GetSlideShow());
scheduler_rpc_in_progress--;
if ( scheduler_rpc_in_progress == 0 ) {
GetCanvas()->ReloadSlideShow(GetSlideShow());
}
}
@ -219,18 +245,23 @@ void CViewTabPage::UpdateInterface()
}
m_hasGraphic = false;
}
int newStatus = ComputeState();
if ( btnAminBg->GetStatus() != newStatus ) {
changed = true;
btnAminBg->SetStatus(newStatus);
}
btnAminBg->SetShowText(m_hasGraphic);
if ( changed ) {
btnAminBg->Refresh();
btnAminBg->Update();
m_canvas->Refresh();
m_canvas->Update();
}
}
void CViewTabPage::CreateSlideShowWindow() {
if ( wSlideShow <= NULL ) {
delete wSlideShow;
}
wSlideShow=new wxWindow(this,-1,wxPoint(30,156),wxSize(290,126),wxNO_BORDER);
m_canvas = new MyCanvas(wSlideShow, wxPoint(0,0), wxSize(290,126), GetSlideShow());
}
@ -242,6 +273,7 @@ void CViewTabPage::ReskinInterface()
lnProjName->SetLineColor(appSkin->GetStaticLineCol());
// gauge
gaugeWUMain->ReskinInterface();
wSlideShow->Destroy();
CreateSlideShowWindow();
}
@ -342,6 +374,20 @@ void CViewTabPage::OnWorkShowGraphics() {
}
}
wxString CViewTabPage::FormatText(const wxString& text, wxDC* dc) {
wxCoord width, height;
dc->GetTextExtent(text, &width, &height);
if ( width > 201 ) {
int i = (int) text.length();
while ( width > 201 ) {
i--;
dc->GetTextExtent(text.substr(0,i) + _T("..."), &width, &height);
}
return text.substr(0,i) + _T("...");
}
return text;
}
void CViewTabPage::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxLogTrace(wxT("Function Start/End"), wxT("CViewTabPage::OnPaint - Begin"));
@ -358,7 +404,7 @@ void CViewTabPage::OnPaint(wxPaintEvent& WXUNUSED(event))
//static: projectFrName,wrkUnitName,gaugePercent,elapsedTimeValue,timeRemainingValue
dc.SetFont(wxFont(9,74,90,92,0,wxT("Arial")));
dc.DrawText(projectFrName, wxPoint(110,49));
dc.DrawText(wrkUnitName, wxPoint(120,71));
dc.DrawText(FormatText(wrkUnitName, &dc), wxPoint(120,71));
dc.DrawText(gaugePercent, wxPoint(290,90));
dc.DrawText(elapsedTimeValue, wxPoint(118,115));
dc.DrawText(timeRemainingValue, wxPoint(130,134));
@ -390,7 +436,7 @@ void CViewTabPage::DrawText()
//static: projectFrName,wrkUnitName,gaugePercent,elapsedTimeValue,timeRemainingValue
dc.SetFont(wxFont(9,74,90,92,0,wxT("Arial")));
dc.DrawText(projectFrName, wxPoint(110,49));
dc.DrawText(wrkUnitName, wxPoint(120,71));
dc.DrawText(FormatText(wrkUnitName, &dc), wxPoint(120,71));
dc.DrawText(gaugePercent, wxPoint(290,90));
dc.DrawText(elapsedTimeValue, wxPoint(118,115));
dc.DrawText(timeRemainingValue, wxPoint(130,134));
@ -449,9 +495,6 @@ MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size, std
LoadSlideShow();
}
MyCanvas::~MyCanvas() {
}
void MyCanvas::LoadSlideShow() {
// Clear out any existings data (for when this is reloading)
// for(int i=0; i< (int) vSlideShow.size(); i++ ) {
@ -545,7 +588,10 @@ WorkunitNotebook::WorkunitNotebook(wxWindow* parent, wxWindowID id, const wxPoin
SetGradientColors(appSkin->GetTabFromColAc(),appSkin->GetTabToColAc(),appSkin->GetTabBrdColAc());
SetActiveTabTextColour(wxColour(255,255,255));
SetGradientColorsInactive(appSkin->GetTabFromColIn(),appSkin->GetTabToColIn(),appSkin->GetTabBrdColIn());
SetNonActiveTabTextColour(wxColour(255,255,255));
char red = (char) (( (int) appSkin->GetTabFromColIn().Red() + (int) appSkin->GetTabToColIn().Red() + 255*3)/5);
char green = (char) (( (int) appSkin->GetTabFromColIn().Green() + (int) appSkin->GetTabToColIn().Green() + 255*3)/5);
char blue = (char) (( (int) appSkin->GetTabFromColIn().Blue() + (int) appSkin->GetTabToColIn().Blue() + 255*3)/5);
SetNonActiveTabTextColour(wxColour(red, green, blue));
m_ImageList.push_back(*(appSkin->GetIcnWorkingWkUnit()));
SetImageList(&m_ImageList);
changeSlideTimer = new wxTimer(this, ID_CHANGE_SLIDE_TIMER);
@ -553,7 +599,6 @@ WorkunitNotebook::WorkunitNotebook(wxWindow* parent, wxWindowID id, const wxPoin
}
WorkunitNotebook::~WorkunitNotebook() {
m_windows.clear();
if ( changeSlideTimer->IsRunning() ) {
changeSlideTimer->Stop();
}
@ -664,8 +709,10 @@ void WorkunitNotebook::Update() {
void WorkunitNotebook::OnChangeSlide(wxTimerEvent& WXUNUSED(event)) {
for(int x = 0; x < (int)m_windows.size(); x ++) {
CViewTabPage *currTab = m_windows[x];
currTab->GetCanvas()->AdvanceSlide();
if ( GetPageImageIndex(x) == 0 ) {
CViewTabPage *currTab = m_windows[x];
currTab->GetCanvas()->AdvanceSlide();
}
}
}

View File

@ -35,7 +35,6 @@ class MyCanvas : public wxScrolledWindow
{
public:
MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size, std::vector<wxBitmap> images);
~MyCanvas();
void OnPaint(wxPaintEvent& event);
void AdvanceSlide();
void ReloadSlideShow(std::vector<wxBitmap> images);
@ -131,10 +130,12 @@ private:
void CreateSlideShowWindow();
void LoadSlideShow(std::vector<wxBitmap> *vSlideShow);
bool Downloading();
int ComputeState();
wxString FormatText(const wxString& text, wxDC* dc);
std::vector<wxBitmap> GetSlideShow();
wxWindow* wSlideShow;
MyCanvas* m_canvas;
bool scheduler_rpc_in_progress;
int scheduler_rpc_in_progress;
};

View File

@ -39,13 +39,13 @@
<icons>
<workingWkUnit>
<imgsrc>graphic/ico_workWU.png</imgsrc>
<frcol>134:179:176</frcol>
<tocol>51:102:102</tocol>
<brdcol>20:82:82</brdcol>
<frcol>51:102:102</frcol>
<tocol>134:179:176</tocol>
<brdcol>51:102:102</brdcol>
</workingWkUnit>
<sleepingWkUnit>
<frcol>134:179:176</frcol>
<tocol>84:175:175</tocol>
<frcol>84:175:175</frcol>
<tocol>134:179:176</tocol>
<brdcol>102:153:153</brdcol>
</sleepingWkUnit>
<defaultStatIcon>