Changes to allow the messages button to alternate between black and red when new alert messages have been recevied

svn path=/trunk/boinc/; revision=10999
This commit is contained in:
Kevin Reed 2006-08-24 17:54:54 +00:00
parent 35d7169058
commit 3fb5cc6ca2
11 changed files with 247 additions and 74 deletions

View File

@ -9278,3 +9278,19 @@ David 23 Aug 2006
html/inc/
prefs.inc
Kevin 24 Aug 2006
- Enhancements to the simple gui
-- Messages button will now alternate between black and red when alert messages have been recieved
-- Additional client states are now shown when no work tabs are available such as 'downloading work'
clientgui/
MainDocument.cpp
sg_BoincSimpleGUI.cpp
sg_BoincSimpleGUI.h
sg_ClientStateIndicator.cpp
sg_ClientStateIndicator.h
sg_ProjectsComponent.cpp
sg_ProjectsComponent.h
sg_SkinClass.cpp

View File

@ -1239,14 +1239,16 @@ int CMainDocument::CachedSimpleGUIUpdate() {
int CMainDocument::GetSimpleGUIWorkCount() {
int iCount = -1;
int iCount = 0;
CachedSimpleGUIUpdate();
CachedStateUpdate();
if (!results.results.empty())
iCount = (int)results.results.size();
for(int i=0;i<results.results.size();i++) {
if ( results.results[i]->active_task ) {
iCount++;
}
}
return iCount;
}

View File

@ -211,8 +211,6 @@ void CSimpleFrame::OnProjectsAttachToProject() {
pWizard->Destroy();
m_pFrameRenderTimer->Start();
//update Project Component
projComponent->UpdateInterface();
} else {
ShowNotCurrentlyConnectedAlert();
}
@ -223,8 +221,10 @@ void CSimpleFrame::OnProjectsAttachToProject() {
void CSimpleFrame::OnFrameRender(wxTimerEvent& WXUNUSED(event)) {
CMainDocument* pDoc = wxGetApp().GetDocument();
if (!projectViewInitialized) {
if (!projectViewInitialized && pDoc->IsConnected()) {
InitProjectView();
} else if ( pDoc->IsConnected() ) {
UpdateProjectView();
}
// Now check to see if we show the empty state or results
if ( pDoc->GetSimpleGUIWorkCount() > 0 ) {
@ -278,7 +278,11 @@ void CSimpleFrame::InitEmptyView()
emptyViewInitialized = true;
}
void CSimpleFrame::UpdateProjectView()
{
//update Project Component
projComponent->UpdateInterface();
}
void CSimpleFrame::InitResultView()
{
CMainDocument* pDoc = wxGetApp().GetDocument();
@ -307,10 +311,8 @@ void CSimpleFrame::InitProjectView()
projectViewInitialized = true;
}
void CSimpleFrame::UpdateResultView(){
wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::UpdateResultView - Function Start"));
CMainDocument* pDoc = wxGetApp().GetDocument();
//update GUI
int resultCnt = (int)pDoc->GetSimpleGUIWorkCount();
wxString strBuffer = wxEmptyString;
//assume they are all inactive
for(int x = 0; x < (int)m_windows.size(); x ++)
@ -320,8 +322,11 @@ void CSimpleFrame::UpdateResultView(){
}
// Update Tabs
RESULT* result;
for(int i = 0; i < resultCnt; i++){
result = pDoc->results.results[i];
for(int i = 0; i < pDoc->results.results.size(); i++){
result = pDoc->result(i);
if ( result == NULL || !result->active_task ) {
continue;
}
// get tab window
bool found = false;
for(int j = 0; j < (int)m_windows.size(); j++)
@ -403,7 +408,6 @@ void CSimpleFrame::UpdateResultView(){
}
}
// Refresh();
wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::UpdateResultView - Function End"));
}
void CSimpleFrame::InitNotebook()

View File

@ -76,6 +76,7 @@ public:
void InitResultView();
void UpdateResultView();
void InitProjectView();
void UpdateProjectView();
void LoadSkinImages();
void ReskinAppGUI();
void InitNotebook();

View File

@ -45,12 +45,12 @@ ClientStateIndicator::ClientStateIndicator(CSimpleFrame* parent,wxPoint coord) :
{
connIndicatorWidth = 14;
connIndicatorHeight = 15;
numOfIndic = 3;
numOfIndic = 5;
indexIndVis = 1;//first will be visible on start
rightPosition = 142;
rightPosition = 118;
topPosition = 5;
stateMessage = wxString("");
clientCurrState = "";
clientState = CLIENT_STATE_NONE;
LoadSkinImages();
CreateComponent();
error_time = 0;
@ -59,8 +59,10 @@ ClientStateIndicator::ClientStateIndicator(CSimpleFrame* parent,wxPoint coord) :
ClientStateIndicator::~ClientStateIndicator()
{
if (m_connRenderTimer) {
m_connRenderTimer->Stop();
delete m_connRenderTimer;
if ( clientState == CLIENT_STATE_ACTION ) {
m_connRenderTimer->Stop();
delete m_connRenderTimer;
}
}
}
@ -88,53 +90,81 @@ void ClientStateIndicator::CreateComponent(){
void ClientStateIndicator::SetActionState(const char* message)
{
Freeze();
//Delete Previous state
DeletePreviousState();
clientCurrState = "connecting";
i_indBg = new ImageLoader(this);
i_indBg->Move(wxPoint(42,74));
i_indBg->LoadImage(g_stateIndBg);
stateMessage = wxString(message);
for(int x = 0; x < numOfIndic; x++){
ImageLoader *i_connInd = new ImageLoader(this);
i_connInd->Move(wxPoint(rightPosition +(connIndicatorWidth+10) * x,84));
i_connInd->LoadImage(g_connInd);
if(x !=0){
i_connInd->Show(false);
if ( clientState != CLIENT_STATE_ACTION ) {
//Delete Previous state
DeletePreviousState();
clientState = CLIENT_STATE_ACTION;
i_indBg = new ImageLoader(this);
i_indBg->Move(wxPoint(42,74));
i_indBg->LoadImage(g_stateIndBg);
for(int x = 0; x < numOfIndic; x++){
ImageLoader *i_connInd = new ImageLoader(this);
i_connInd->Move(wxPoint(rightPosition +(connIndicatorWidth+10) * x,84));
i_connInd->LoadImage(g_connInd);
if(x !=0){
i_connInd->Show(false);
}
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);
}
Thaw();
}
void ClientStateIndicator::SetPausedState(const char* message)
{
Freeze();
stateMessage = wxString(message);
if ( clientState != CLIENT_STATE_PAUSED ) {
//Delete Previous state
DeletePreviousState();
clientState = CLIENT_STATE_PAUSED;
i_indBg = new ImageLoader(this);
i_indBg->Move(wxPoint(42,74));
i_indBg->LoadImage(g_stateIndBg);
for(int x = 0; x < numOfIndic; x++){
ImageLoader *i_connInd = new ImageLoader(this);
i_connInd->Move(wxPoint(rightPosition +(connIndicatorWidth+10) * x,84));
i_connInd->LoadImage(g_connInd);
m_connIndV.push_back(i_connInd);
}
m_connIndV.push_back(i_connInd);
}
//set animation timer for interface
m_connRenderTimer = new wxTimer(this, ID_ANIMATIONRENDERTIMER);
wxASSERT(m_connRenderTimer);
m_connRenderTimer->Start(400);
Thaw();
}
void ClientStateIndicator::SetNoActionState(const char* message)
{
Freeze();
//Delete Previous state
DeletePreviousState();
clientCurrState = "nowork";
i_indBg = new ImageLoader(this);
i_indBg->Move(wxPoint(42,74));
i_indBg->LoadImage(g_stateIndBg);
stateMessage = wxString(message);
i_errorInd = new ImageLoader(this);
i_errorInd->Move(wxPoint(rightPosition,84));
i_errorInd->LoadImage(g_errorInd);
i_errorInd->Refresh();
if ( clientState != CLIENT_STATE_ERROR ) {
//Delete Previous state
DeletePreviousState();
clientState = CLIENT_STATE_ERROR;
i_indBg = new ImageLoader(this);
i_indBg->Move(wxPoint(42,74));
i_indBg->LoadImage(g_stateIndBg);
i_errorInd = new ImageLoader(this);
i_errorInd->Move(wxPoint(rightPosition+24,84));
i_errorInd->LoadImage(g_errorInd);
i_errorInd->Refresh();
}
Thaw();
}
void ClientStateIndicator::DeletePreviousState()
{
if(clientCurrState == "connecting"){
if (m_connRenderTimer) {
if(clientState == CLIENT_STATE_ACTION || clientState == CLIENT_STATE_PAUSED){
if (m_connRenderTimer && clientState == CLIENT_STATE_ACTION) {
m_connRenderTimer->Stop();
delete m_connRenderTimer;
}
@ -147,7 +177,7 @@ void ClientStateIndicator::DeletePreviousState()
}
//delete ind bg
delete i_indBg;
}else if(clientCurrState == "nowork"){
}else if(clientState == CLIENT_STATE_ERROR){
delete i_errorInd;
//delete ind bg
delete i_indBg;
@ -177,9 +207,12 @@ void ClientStateIndicator::ReskinInterface()
void ClientStateIndicator::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
//static: message
//set font
dc.SetFont(wxFont(9,74,90,90,0,wxT("Arial")));
dc.DrawText(stateMessage, wxPoint(47,120));
// center the text
wxCoord height, width;
dc.GetTextExtent(stateMessage, &width, &height);
dc.DrawText(stateMessage, wxPoint(176-width/2,120));
}
void ClientStateIndicator::OnEraseBackground(wxEraseEvent& event){
@ -196,18 +229,40 @@ void ClientStateIndicator::OnEraseBackground(wxEraseEvent& event){
}
bool ClientStateIndicator::DownloadingResults() {
bool return_value = false;
CMainDocument* pDoc = wxGetApp().GetDocument();
if ( pDoc->results.results.size() > 0 ) {
RESULT* result;
for(unsigned int i=0; !return_value && i < pDoc->results.results.size(); i++ ) {
result = pDoc->result(i);
if ( result != NULL && result->state == RESULT_FILES_DOWNLOADING ) {
return_value = true;
}
}
}
return return_value;
}
void ClientStateIndicator::DisplayState() {
CMainDocument* pDoc = wxGetApp().GetDocument();
if ( pDoc->IsReconnecting() ) {
SetActionState("Retrieving status.");
error_time = 0;
SetActionState(_T("Retrieving current status."));
} else if ( pDoc->IsConnected() && pDoc->state.projects.size() == 0) {
error_time = 0;
SetPausedState(_T("You don't have any projects. Please Add a Project."));
} else if ( DownloadingResults() ) {
error_time = 0;
SetActionState(_T("Downloading work from the server."));
} else {
if ( error_time == 0 ) {
error_time = time(NULL) + 30;
SetActionState("Retrieving status");
error_time = time(NULL) + 15;
SetActionState(_T("Retrieving current status"));
} else if ( error_time < time(NULL) ) {
SetNoActionState("No work available to process");
SetNoActionState(_T("No work available to process"));
} else {
SetActionState("Retrieving status");
SetActionState(_T("Retrieving current status"));
}
}
}

View File

@ -45,7 +45,7 @@ public:
std::vector<ImageLoader*> m_connIndV;
wxTimer *m_connRenderTimer;
wxString stateMessage;
std::string clientCurrState;
int clientState;
/// Constructors
ClientStateIndicator();
ClientStateIndicator(CSimpleFrame* parent, wxPoint coord);
@ -60,6 +60,8 @@ private:
void SetActionState(const char* message);
void SetNoActionState(const char* message);
void SetPausedState(const char* message);
bool DownloadingResults();
wxImage *g_stateIndBg;
wxImage *g_compBg;
wxImage *g_connInd;
@ -75,5 +77,10 @@ private:
DECLARE_EVENT_TABLE()
};
#define CLIENT_STATE_NONE 0
#define CLIENT_STATE_ACTION 1
#define CLIENT_STATE_PAUSED 2
#define CLIENT_STATE_ERROR 3
#endif

View File

@ -34,6 +34,7 @@
#include "app_ipc.h"
#define ID_CHECKFORERRORMESSAGETIMER 13000
IMPLEMENT_DYNAMIC_CLASS(CProjectsComponent, wxPanel)
@ -42,8 +43,11 @@ BEGIN_EVENT_TABLE(CProjectsComponent, wxPanel)
EVT_PAINT(CProjectsComponent::OnPaint)
EVT_BUTTON(-1,CProjectsComponent::OnBtnClick)
EVT_ERASE_BACKGROUND(CProjectsComponent::OnEraseBackground)
EVT_TIMER(ID_CHECKFORERRORMESSAGETIMER, CProjectsComponent::CheckForErrorMessages)
END_EVENT_TABLE()
int CProjectsComponent::lastMessageId = 0;
CProjectsComponent::CProjectsComponent() {}
@ -58,9 +62,19 @@ CProjectsComponent::CProjectsComponent(CSimpleFrame* parent,wxPoint coord) :
LoadSkinImages();
CreateComponent();
receivedErrorMessage = false;
alertMessageDisplayed = false;
checkForMessagesTimer = new wxTimer(this, ID_CHECKFORERRORMESSAGETIMER);
checkForMessagesTimer->Start(5000);
}
CProjectsComponent::~CProjectsComponent() {}
CProjectsComponent::~CProjectsComponent() {
if ( checkForMessagesTimer->IsRunning() ) {
checkForMessagesTimer->Stop();
}
delete checkForMessagesTimer;
}
void CProjectsComponent::LoadSkinImages(){
//app skin class
@ -82,6 +96,9 @@ void CProjectsComponent::LoadSkinImages(){
// messages
g_messages = new wxImage(dirPref + appSkin->GetBtnMessages(), wxBITMAP_TYPE_PNG);
g_messagesClick = new wxImage(dirPref + appSkin->GetBtnMessages(), wxBITMAP_TYPE_PNG);
// error messages
g_alertMessages = new wxImage(dirPref + appSkin->GetBtnAlertMessages(), wxBITMAP_TYPE_PNG);
g_alertMessagesClick = new wxImage(dirPref + appSkin->GetBtnAlertMessages(), wxBITMAP_TYPE_PNG);
// pause
g_pause = new wxImage(dirPref + appSkin->GetBtnPause(), wxBITMAP_TYPE_PNG);
g_pauseClick = new wxImage(dirPref + appSkin->GetBtnPause(), wxBITMAP_TYPE_PNG);
@ -107,6 +124,8 @@ void CProjectsComponent::LoadSkinImages(){
btmpAddProjC= wxBitmap(g_addProjClick);
btmpMessages= wxBitmap(g_messages);
btmpMessagesC= wxBitmap(g_messagesClick);
btmpAlertMessages= wxBitmap(g_alertMessages);
btmpAlertMessagesC= wxBitmap(g_alertMessagesClick);
btmpPause= wxBitmap(g_pause);
btmpPauseC= wxBitmap(g_pauseClick);
btmpResume= wxBitmap(g_resume);
@ -187,6 +206,11 @@ void CProjectsComponent::CreateComponent()
btnMessages=new wxBitmapButton(this,-1,btmpMessages,wxPoint(11,86),wxSize(70,20),wxNO_BORDER);
btnMessages->SetBitmapSelected(btmpMessagesC);
btnMessages->SetToolTip(ttMessages);
wxToolTip *ttAlertMessages = new wxToolTip(wxT("Messages"));
btnAlertMessages=new wxBitmapButton(this,-1,btmpAlertMessages,wxPoint(11,86),wxSize(70,20),wxNO_BORDER);
btnAlertMessages->SetBitmapSelected(btmpAlertMessagesC);
btnAlertMessages->SetToolTip(ttAlertMessages);
btnAlertMessages->Show(false);
//spacer
wxWindow *w_sp1 = new wxWindow(this,-1,wxPoint(83,91),wxSize(2,11));
i_spacer = new ImageLoader(w_sp1);
@ -334,6 +358,31 @@ void CProjectsComponent::RemoveProject(std::string prjUrl)
void CProjectsComponent::UpdateInterface()
{
CMainDocument* pDoc = wxGetApp().GetDocument();
// Check to see if error messages have been received
if ( receivedErrorMessage ) {
Freeze();
if ( alertMessageDisplayed ) {
btnAlertMessages->Show(false);
btnMessages->Show(true);
alertMessageDisplayed = false;
} else {
btnAlertMessages->Show(true);
btnMessages->Show(false);
alertMessageDisplayed = true;
}
Thaw();
} else {
if ( alertMessageDisplayed ) {
Freeze();
btnAlertMessages->Show(false);
btnMessages->Show(true);
alertMessageDisplayed = false;
Thaw();
}
}
// Check number of projects
int oldProjCnt = m_projCnt;
m_projCnt = pDoc->GetProjectCount();
if(m_projCnt == oldProjCnt){
@ -393,6 +442,10 @@ void CProjectsComponent::ReskinInterface()
btnMessages->SetBackgroundColour(appSkin->GetAppBgCol());
btnMessages->SetBitmapLabel(btmpMessages);
btnMessages->SetBitmapSelected(btmpMessagesC);
// alert messages btn
btnAlertMessages->SetBackgroundColour(appSkin->GetAppBgCol());
btnAlertMessages->SetBitmapLabel(btmpAlertMessages);
btnAlertMessages->SetBitmapSelected(btmpAlertMessagesC);
// pause btn
btnPause->SetBackgroundColour(appSkin->GetAppBgCol());
btnPause->SetBitmapLabel(btmpPause);
@ -522,7 +575,8 @@ void CProjectsComponent::OnBtnClick(wxCommandEvent& event){ //init function
}else if(m_wxBtnObj==btnAddProj){
pFrame->OnProjectsAttachToProject();
btnAddProj->Refresh();
}else if(m_wxBtnObj==btnMessages){
}else if(m_wxBtnObj==btnMessages || m_wxBtnObj==btnAlertMessages){
MessagesViewed();
CDlgMessages* pDlg = new CDlgMessages(NULL,appSkin->GetSkinsFolder()+_T("/")+appSkin->GetSkinName()+_T("/"));
wxASSERT(pDlg);
pDlg->ShowModal();
@ -588,4 +642,28 @@ void CProjectsComponent::DrawBackImg(wxEraseEvent& event,wxWindow *win,wxBitmap
}
break;}
}
}
void CProjectsComponent::CheckForErrorMessages(wxTimerEvent& WXUNUSED(event)) {
CMainDocument* pDoc = wxGetApp().GetDocument();
MESSAGE* message;
// Only look at the messages recieved since the last time we looked
if ( pDoc->GetMessageCount() > lastMessageId ) {
// Loop through and check for any messages recieved that are error messages
for(int i=lastMessageId; i < pDoc->messages.messages.size(); i++) {
lastMessageId = i+1;
message = pDoc->message(i);
if ( message != NULL && message->priority == MSG_PRIORITY_ERROR ) {
receivedErrorMessage = true;
checkForMessagesTimer->Stop();
lastMessageId = pDoc->messages.messages.size();
break;
}
}
}
}
void CProjectsComponent::MessagesViewed() {
receivedErrorMessage = false;
checkForMessagesTimer->Start();
}

View File

@ -68,6 +68,8 @@ public:
wxImage *g_addProjClick;
wxImage *g_messages;
wxImage *g_messagesClick;
wxImage *g_alertMessages;
wxImage *g_alertMessagesClick;
wxImage *g_pause;
wxImage *g_pauseClick;
wxImage *g_resume;
@ -84,6 +86,8 @@ public:
wxBitmap btmpAddProjC;
wxBitmap btmpMessages;
wxBitmap btmpMessagesC;
wxBitmap btmpAlertMessages;
wxBitmap btmpAlertMessagesC;
wxBitmap btmpPause;
wxBitmap btmpPauseC;
wxBitmap btmpResume;
@ -96,6 +100,7 @@ public:
wxBitmapButton *btnArwRight;
wxBitmapButton *btnAddProj;
wxBitmapButton *btnMessages;
wxBitmapButton *btnAlertMessages;
wxBitmapButton *btnPause;
wxBitmapButton *btnResume;
wxBitmapButton *btnPreferences;
@ -115,7 +120,7 @@ public:
void ReskinInterface();
void OnBtnClick(wxCommandEvent& event);
void OnPaint(wxPaintEvent& event);
DECLARE_EVENT_TABLE()
protected:
@ -126,9 +131,15 @@ protected:
void OnEraseBackground(wxEraseEvent& event);
void DrawBackImg(wxEraseEvent& event,wxWindow *win,wxBitmap & bitMap,int opz);
};
private:
wxTimer* checkForMessagesTimer;
bool receivedErrorMessage;
bool alertMessageDisplayed;
static int lastMessageId;
void CheckForErrorMessages(wxTimerEvent& WXUNUSED(event));
void MessagesViewed();
};
#endif

View File

@ -231,6 +231,12 @@ int SkinClass::LoadSkinXML(){
SetBtnAlertMessages(wxString( val.c_str(), wxConvUTF8 ));
skinImageArray->Add(wxString( val.c_str(), wxConvUTF8 ));
}
}else if(match_tag(buf, "<alert_messages>")){
mf.fgets(buf, 256);
if (parse_str(buf, "<imgsrc>", val)) {
SetBtnAlertMessages(wxString( val.c_str(), wxConvUTF8 ));
skinImageArray->Add(wxString( val.c_str(), wxConvUTF8 ));
}
}else if(match_tag(buf, "<save>")){
mf.fgets(buf, 256);
if (parse_str(buf, "<imgsrc>", val)) {

View File

@ -98,8 +98,6 @@ void StatImageLoader::OnMenuLinkClicked(wxCommandEvent& event)
}
void StatImageLoader::OnProjectDetach() {
wxLogTrace(wxT("Function Start/End"), wxT("StatImageLoader::OnProjectDetach - Function Begin"));
wxInt32 iAnswer = 0;
std::string strProjectName;
wxString strMessage = wxEmptyString;
@ -143,8 +141,6 @@ void StatImageLoader::OnProjectDetach() {
pDoc->ProjectDetach(indexOfProj);
pComp->RemoveProject(m_prjUrl);
}
wxLogTrace(wxT("Function Start/End"), wxT("StatImageLoader::OnProjectDetach - Function End"));
}

View File

@ -56,7 +56,7 @@ CViewTabPage::CViewTabPage(wxFlatNotebook* parent,int index,std::string name,std
m_hasGraphic = false;
// init doc and results data
pDoc = wxGetApp().GetDocument();
resultWU = pDoc->results.results[m_tabIndex];
resultWU = pDoc->result(m_tabIndex);
//load skin images
LoadSkinImages();
//create page
@ -145,7 +145,7 @@ void CViewTabPage::CreatePage()
}
void CViewTabPage::UpdateInterface()
{
resultWU = pDoc->results.results[m_tabIndex];
resultWU = pDoc->result(m_tabIndex);
wxString strBuffer = wxEmptyString;
//Gauge
gaugeWUMain->UpdateValue(floor(resultWU->fraction_done * 100000)/1000);
@ -238,8 +238,6 @@ void CViewTabPage::SGUITimeFormat(float fBuffer, wxString& strBuffer) const {
}
void CViewTabPage::OnWorkShowGraphics() {
wxLogTrace(wxT("Function Start/End"), wxT("CViewTabPage::OnWorkShowGraphics - Function Begin"));
wxInt32 iAnswer = 0;
wxString strMachineName = wxEmptyString;
@ -277,7 +275,6 @@ void CViewTabPage::OnWorkShowGraphics() {
);
}
wxLogTrace(wxT("Function Start/End"), wxT("CViewTabPage::OnWorkShowGraphics - Function End"));
}
void CViewTabPage::OnPaint(wxPaintEvent& WXUNUSED(event))
{