示例#1
0
int TestAARHUD::RecursivelyAddTasks(const std::string& indent, int curIndex,
                                    const dtActors::TaskActorProxy* taskProxy, int& numCompleted)
{
   char clin[HUDCONTROLMAXTEXTSIZE];
   int totalNumAdded = 0;

   if (curIndex < (int) mTaskTextList.size())
   {
      // update the text for this task
      const dtActors::TaskActor* task = dynamic_cast<const dtActors::TaskActor*>(&(taskProxy->GetGameActor()));
      if (task->IsComplete())
      {
         numCompleted ++;

         snprintf(clin, HUDCONTROLMAXTEXTSIZE, "%s %s - %s - %.2f", indent.c_str(), task->GetName().c_str(),
            "Y", task->GetScore());
         UpdateStaticText(mTaskTextList[curIndex + totalNumAdded], clin, 0.1f, 1.0f, 0.1f);
      }
      else
      {
         snprintf(clin, HUDCONTROLMAXTEXTSIZE, "%s %s - %s - %.2f", indent.c_str(), task->GetName().c_str(),
            "N", task->GetScore());
         UpdateStaticText(mTaskTextList[curIndex + totalNumAdded], clin, 1.0f, 1.0f, 1.0f);
      }

      totalNumAdded += 1;

      // recurse for each child
      std::vector<const dtActors::TaskActorProxy*> children;
      taskProxy->GetAllSubTasks(children);
      if (!children.empty())
      {
         for (int i = 0; i < (int)children.size(); i ++)
         {
            const dtActors::TaskActorProxy* childProxy = dynamic_cast<const dtActors::TaskActorProxy *> (children[i]);
            totalNumAdded += RecursivelyAddTasks(indent + "     ", curIndex + totalNumAdded, childProxy, numCompleted);
         }
      }
   }

   return totalNumAdded;
}
示例#2
0
void TestAARHUD::UpdateMediumDetailData()
{
   if (*mHUDState == HUDState::MEDIUM || *mHUDState == HUDState::MAXIMUM)
   {
      char clin[HUDCONTROLMAXTEXTSIZE]; // general buffer to print
      std::vector<dtCore::RefPtr<dtGame::GameActorProxy> > tasks;
      int numAdded = 0;
      int numComplete = 0;

      mTaskComponent->GetTopLevelTasks(tasks);

      // start our recursive method on each top level task
      for (unsigned int i = 0; i < tasks.size(); i ++)
      {
         dtActors::TaskActorProxy *taskProxy =
            dynamic_cast<dtActors::TaskActorProxy *> (tasks[i].get());
         numAdded += RecursivelyAddTasks("", numAdded, taskProxy, numComplete);
      }

      // blank out any of our placeholder task text controls that were left over
      for (int i = numAdded; i < (int)mTaskTextList.size(); i ++)
      {
         UpdateStaticText(mTaskTextList[i], "");
      }

      // update our task header
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "Tasks (%i of %i):", numComplete, numAdded);
      if (numComplete < numAdded)
      {
         UpdateStaticText(mTasksHeaderText, clin, 1.0f, 1.0f, 1.0f);
      }
      else
      {
         UpdateStaticText(mTasksHeaderText, clin, 0.1f, 1.0f, 0.1f);
      }
   }
}
示例#3
0
HUDState& TestAARHUD::CycleToNextHUDState()
{
   if (*mHUDState == HUDState::MINIMAL) // MINIMAL - go to MEDIUM
   {
      mHUDState = &HUDState::MEDIUM;
      UpdateStaticText(mFirstTipText, "(F2 for MAX HUD)");
      UpdateStaticText(mHelpTipText, "(F2 for MED HUD)");
      mLastHUDStateBeforeHelp = mHUDState;
   }
   else if (*mHUDState == HUDState::MEDIUM) // MEDIUM - go to MAXIMUM
   {
      mHUDState = &HUDState::MAXIMUM;
      UpdateStaticText(mFirstTipText, "(F2 for NO HUD)");
      UpdateStaticText(mHelpTipText, "(F2 for MAX HUD)");
      mLastHUDStateBeforeHelp = mHUDState;
   }
   else if (*mHUDState == HUDState::MAXIMUM) // MAXIMUM, go to NONE
   {
      mHUDState = &HUDState::NONE;
      UpdateStaticText(mFirstTipText, "(F2 for MIN HUD)");
      UpdateStaticText(mHelpTipText, "(F2 for NO HUD)");
      mLastHUDStateBeforeHelp = mHUDState;
   }
   else if (*mHUDState == HUDState::NONE) // NONE - go to MINIMUM
   {
      mHUDState = &HUDState::MINIMAL;
      UpdateStaticText(mFirstTipText, "(F2 for MED HUD)");
      UpdateStaticText(mHelpTipText, "(F2 for MIN HUD)");
      mLastHUDStateBeforeHelp = mHUDState;
   }
   else // HELP - go to last state before Help
   {
      mHUDState = mLastHUDStateBeforeHelp;
    }

   // we've changed our state, so reset our hide/show status
   UpdateState();

   return *mHUDState;
}
示例#4
0
void TestAARHUD::TickHUD()
{
   int x(0), y(0), w(0), h(0);
   mWin->GetPosition(x, y, w, h);
   float curYPos;

   if (*mHUDState != HUDState::HELP)
   {
      char clin[HUDCONTROLMAXTEXTSIZE]; // general buffer to print

      // Playback State
      if (dtGame::LogStateEnumeration::LOGGER_STATE_IDLE == mLogController->GetLastKnownStatus().GetStateEnum())
      {
         UpdateStaticText(mStateText, "IDLE", 1.0f, 1.0f, 1.0f);
      }
      else if (dtGame::LogStateEnumeration::LOGGER_STATE_PLAYBACK == mLogController->GetLastKnownStatus().GetStateEnum())
      {
         UpdateStaticText(mStateText, "PLAYBACK", 0.1f, 1.0f, 0.1f);
      }
      else // if (dtGame::LogStateEnumeration::LOGGER_STATE_RECORD == mLogController->GetLastKnownStatus().GetStateEnum())
      {
         UpdateStaticText(mStateText, "RECORD", 1.0f, 0.1f, 0.1f);
      }

      // Sim Time
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "SimTime: %.2f", GetGameManager()->GetSimulationTime());
      curYPos = mTextYTopOffset;
      UpdateStaticText(mSimTimeText, clin, -1.0f, -1.0f, -1.0f, w - mRightTextXOffset, curYPos);

      // speed factor
      curYPos += mTextHeight + 2;
      if (!GetGameManager()->IsPaused())
      {
         snprintf(clin, HUDCONTROLMAXTEXTSIZE, "Speed: %.2fX", GetGameManager()->GetTimeScale());
         UpdateStaticText(mSpeedFactorText, clin, 1.0f, 1.0f, 1.0f, w - mRightTextXOffset, curYPos);
      }
      else
      {
         UpdateStaticText(mSpeedFactorText, "Speed: *Paused*", 1.0f, 0.1f, 0.1f, w - mRightTextXOffset, curYPos);
      }

      UpdateMediumDetailData();
      UpdateHighDetailData((int)(w - mRightTextXOffset), curYPos);
   }
}
示例#5
0
void CSimpleTaskPanel::UpdatePanel(bool delayShow) {
    wxString s = wxEmptyString;
    wxString projName = wxEmptyString;
    TaskSelectionData *selData;
    CMainDocument*      pDoc = wxGetApp().GetDocument();
    wxASSERT(pDoc);
    int                 workCount = pDoc->GetSimpleGUIWorkCount();

    // Workaround for Linux refresh problem
    static bool        wasDelayed = false;

#ifndef __WXMAC__
    Freeze();
#endif
    
    if ((workCount <= 0) || delayShow) {
        if ((workCount != m_oldWorkCount) || delayShow) {
            wasDelayed = true;
            m_myTasksLabel->Hide();
            m_TaskSelectionCtrl->Hide();
            m_TaskProjectLabel->Hide();
            m_TaskProjectName->Hide();
#if SELECTBYRESULTNAME
            m_TaskApplicationName->Hide();
#endif  // SELECTBYRESULTNAME
            m_SlideShowArea->Hide();
            m_ElapsedTimeValue->Hide();
            m_TimeRemainingValue->Hide();
            if (m_iPctDoneX10 >= 0) {
                m_iPctDoneX10 = -1;
                m_ProgressBar->Hide();
            }
            m_ProgressValueText->Hide();
            m_TaskCommandsButton->Hide();
            this->Layout();

#ifdef __WXMAC__
            m_ProgressRect = m_ProgressBar->GetRect();
            m_ProgressRect.Inflate(0, -2);
            m_ProgressRect.Offset(0, -2);
#endif
        }
        
        DisplayIdleState();
        
    } else {
        if ((m_oldWorkCount == 0) || wasDelayed) {
            wasDelayed = false;
            m_myTasksLabel->Show();
            m_TaskSelectionCtrl->Show();
            m_TaskProjectLabel->Show();
            m_TaskProjectName->Show();
#if SELECTBYRESULTNAME
            m_TaskApplicationName->Show();
#endif  // SELECTBYRESULTNAME
            m_SlideShowArea->Show();
            m_ElapsedTimeValue->Show();
            m_TimeRemainingValue->Show();
            m_ProgressBar->Show();
            m_ProgressValueText->Show();
            m_TaskCommandsButton->Show();
            this->Layout();
    
#ifdef __WXMAC__
            m_ProgressRect = m_ProgressBar->GetRect();
            m_ProgressRect.Inflate(0, -2);
            m_ProgressRect.Offset(0, -2);
#endif
        }

        UpdateTaskSelectionList(false);
        
        // We now have valid result pointers, so extract our data
        int count = m_TaskSelectionCtrl->GetCount();
        if (count <= 0) {
            m_CurrentTaskSelection = -1;
        } else {
            if ((m_CurrentTaskSelection < 0) || (m_CurrentTaskSelection > count -1)) {
                m_TaskSelectionCtrl->SetSelection(0);
                m_CurrentTaskSelection = 0;
                m_bStableTaskInfoChanged = true;
            }
            selData = (TaskSelectionData*)m_TaskSelectionCtrl->GetClientData(m_CurrentTaskSelection);
            RESULT* result = selData->result;
            if (result) {
                if (m_bStableTaskInfoChanged) {
#if SELECTBYRESULTNAME
                    wxString str = wxEmptyString;
                    GetApplicationAndProjectNames(result, &s, &projName);
                    str.Printf(_("Application: %s"), s.c_str());
                    UpdateStaticText(&m_TaskApplicationName, str);
                    UpdateStaticText(&m_TaskProjectName, projName);
#else   // SELECTBYRESULTNAME
                    GetApplicationAndProjectNames(result, NULL, &projName);
#endif  // SELECTBYRESULTNAME
                    UpdateStaticText(&m_TaskProjectName, projName);
                    m_SlideShowArea->AdvanceSlideShow(false, true);
                    m_bStableTaskInfoChanged = false;
                }
                float f = result->elapsed_time;
                if (f == 0.) f = result->current_cpu_time;
//                f = result->final_elapsed_time;
                UpdateStaticText(&m_ElapsedTimeValue, GetElapsedTimeString(f));
                UpdateStaticText(&m_TimeRemainingValue, GetTimeRemainingString(result->estimated_cpu_time_remaining));
                int pctDoneX10 = result->fraction_done * 1000.0;
                if (m_iPctDoneX10 != pctDoneX10) {
                    int pctDone = pctDoneX10 / 10;
                    if (m_iPctDoneX10 != (pctDone * 10)) {
                        m_ProgressBar->SetValue(pctDone);
                    }
                    s.Printf(_("%.3f%%"), result->fraction_done*100);
                    m_iPctDoneX10 = pctDoneX10;
                    UpdateStaticText(&m_ProgressValueText, s);
                }
                UpdateStaticText(&m_StatusValueText, GetStatusString(result));
            } else {
                UpdateStaticText(&m_TaskProjectName, m_sNotAvailableString);
#if SELECTBYRESULTNAME
                UpdateStaticText(&m_TaskApplicationName, _("Application: Not available") );
#endif  // SELECTBYRESULTNAME
                UpdateStaticText(&m_ElapsedTimeValue, GetElapsedTimeString(-1.0));
                UpdateStaticText(&m_TimeRemainingValue, GetTimeRemainingString(-1.0));
                if (m_iPctDoneX10 >= 0) {
                    m_iPctDoneX10 = -1;
                    m_ProgressBar->Hide();
                }
                UpdateStaticText(&m_ProgressValueText, wxEmptyString);
                UpdateStaticText(&m_StatusValueText, GetStatusString(NULL));
            }
        }
    }
    m_oldWorkCount = workCount;

#ifndef __WXMAC__
    Thaw();
#endif
}
示例#6
0
void CSimpleTaskPanel::DisplayIdleState() {
    CMainDocument*      pDoc = wxGetApp().GetDocument();
    wxASSERT(pDoc);
            
    if ( pDoc->IsReconnecting() ) {
        error_time = 0;
        UpdateStaticText(&m_StatusValueText, _("Retrieving current status."));
    } else if ( pDoc->IsConnected() && pDoc->state.projects.size() == 0) {
        error_time = 0;
        UpdateStaticText(&m_StatusValueText, m_sNoProjectsString);
    } else if ( DownloadingResults() ) {
        error_time = 0;
        UpdateStaticText(&m_StatusValueText, _("Downloading work from the server."));
    } else if ( Suspended() ) {
        CC_STATUS status;
        pDoc->GetCoreClientStatus(status);
        if ( status.task_suspend_reason & SUSPEND_REASON_BATTERIES ) {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended:  Running On Batteries."));
        } else if ( status.task_suspend_reason & SUSPEND_REASON_USER_ACTIVE ) {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended:  User Active."));
        } else if ( status.task_suspend_reason & SUSPEND_REASON_USER_REQ ) {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended:  User paused processing."));
        } else if ( status.task_suspend_reason & SUSPEND_REASON_TIME_OF_DAY ) {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended:  Time of Day."));
        } else if ( status.task_suspend_reason & SUSPEND_REASON_BENCHMARKS ) {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended:  Benchmarks Running."));
        } else {
            UpdateStaticText(&m_StatusValueText, _("Processing Suspended."));
        }
    } else if ( ProjectUpdateScheduled() ) {
        error_time = 0;
        UpdateStaticText(&m_StatusValueText, _("Waiting to contact project servers."));
    } else {
        if ( error_time == 0 ) {
            error_time = time(NULL) + 10;
            UpdateStaticText(&m_StatusValueText, _("Retrieving current status"));
        } else if ( error_time < time(NULL) ) {
            // TODO: should we display "ERROR" like old Simple GUI?
            if ( pDoc->IsConnected() ) {
                UpdateStaticText(&m_StatusValueText, _("No work available to process"));
            } else {
                UpdateStaticText(&m_StatusValueText, _("Unable to connect to the core client"));
            }
        } else {
            UpdateStaticText(&m_StatusValueText, _("Retrieving current status"));
        }
    }
}
示例#7
0
void CSimpleProjectPanel::UpdateInterface() {
    int n, count = -1;
    bool b_needMenuRebuild = false;
    wxString str = wxEmptyString;
    wxString projName = wxEmptyString;
    CMainDocument* pDoc = wxGetApp().GetDocument();

    wxASSERT(pDoc);

    // Should we display the synchronize button instead of the
    //   attach to project button?
    if ( pDoc->IsConnected() ) {
        CC_STATUS       status;
        int             is_acct_mgr_detected = 0;

        pDoc->GetCoreClientStatus(status);

        if (pDoc->m_iAcct_mgr_info_rpc_result == 0) {
            // We use an integer rather than a bool to force action the first time
            is_acct_mgr_detected = pDoc->ami.acct_mgr_url.size() ? 1 : 0;
            
            if ((m_UsingAccountManager != is_acct_mgr_detected) || (!m_TaskAddProjectButton->IsEnabled())) {
                m_UsingAccountManager = is_acct_mgr_detected;
                if (is_acct_mgr_detected) {
                    m_TaskAddProjectButton->SetLabel(m_sSynchronizeString);
                    m_TaskAddProjectButton->Enable();
                    m_TaskAddProjectButton->SetToolTip(m_sSynchronizeToolTip);
                } else {
                    m_TaskAddProjectButton->SetLabel(m_sAddProjectString);
                    if (!status.disallow_attach) {
                        m_TaskAddProjectButton->Enable();
                        m_TaskAddProjectButton->SetToolTip(m_sAddProjectToolTip);
                   }
                }
                this->Layout();
            }
        } else {
            m_TaskAddProjectButton->Disable();
        }

        UpdateProjectList();
        
        count = m_ProjectSelectionCtrl->GetCount();
    }
    if (count > 0) {
        n = m_ProjectSelectionCtrl->GetSelection();
        if ((n < 0) || (n > count -1)) {
            m_ProjectSelectionCtrl->SetSelection(0);
            n = 0;
        }
        
        // Check to see if we need to rebuild the menu
        char* ctrl_url = ((ProjectSelectionData*)m_ProjectSelectionCtrl->GetClientData(n))->project_url;
        if (strcmp(m_CurrentSelectedProjectURL, ctrl_url)) {
            b_needMenuRebuild = true;
            strncpy(m_CurrentSelectedProjectURL, ctrl_url, sizeof(m_CurrentSelectedProjectURL));
        }
        
        PROJECT* project = pDoc->state.lookup_project(ctrl_url);
        if ( project != NULL && project->last_rpc_time > m_Project_last_rpc_time ) {
            b_needMenuRebuild = true;
            m_Project_last_rpc_time = project->last_rpc_time;
        }
        
        if (b_needMenuRebuild) {
            m_ProjectWebSitesButton->RebuildMenu();
        }

        m_ProjectWebSitesButton->Enable();
        m_ProjectCommandsButton->Enable();
        
        if (m_fDisplayedCredit != project->user_total_credit) {
            str.Printf(wxT("%s: %s"),
                m_sTotalWorkDoneString.c_str(),
                format_number(project->user_total_credit, 0)
            );
            UpdateStaticText(&m_TotalCreditValue, str);
            m_TotalCreditValue->SetName(str);   // For accessibility on Windows
        }
        projName = m_ProjectSelectionCtrl->GetStringSelection();
        str.Printf(_("Pop up a menu of web sites for project %s"), projName.c_str());
        m_ProjectWebSitesButton->SetToolTip(str);
        str.Printf(_("Pop up a menu of commands to apply to project %s"), projName.c_str());
        m_ProjectCommandsButton->SetToolTip(str);
    } else {
        m_ProjectWebSitesButton->Disable();
        m_ProjectCommandsButton->Disable();
        m_CurrentSelectedProjectURL[0] = '\0';
        m_fDisplayedCredit = -1.0;
        UpdateStaticText(&m_TotalCreditValue, wxEmptyString);
        m_TotalCreditValue->SetName(wxEmptyString);   // For accessibility on Windows
        m_ProjectWebSitesButton->SetToolTip(wxEmptyString);
        m_ProjectCommandsButton->SetToolTip(wxEmptyString);
    }
}
void CSimpleTaskPopupButton::OnTasksCommandButton(wxMouseEvent& /*event*/) {
    CMainDocument*      pDoc = wxGetApp().GetDocument();
    bool                enableShowGraphics = true;
    bool                enableAbort = true;
    CC_STATUS           status;
    wxString            strMachineName;
    
    wxASSERT(pDoc);
    
    TaskSelectionData* selData = ((CSimpleTaskPanel*)GetParent())->GetTaskSelectionData();
    if (selData == NULL) return;

    RESULT* result = lookup_result(selData->project_url, selData->result_name);

    if (!result) return;
    
    if (result->suspended_via_gui) {
        m_TaskSuspendedViaGUI = true;
        m_SuspendResumeMenuItem->SetItemLabel(_("Resume"));
        m_SuspendResumeMenuItem->SetHelp(_("Resume work for this task."));
    } else {
        m_TaskSuspendedViaGUI = false;
        m_SuspendResumeMenuItem->SetItemLabel(_("Suspend"));
        m_SuspendResumeMenuItem->SetHelp(_("Suspend work for this task."));
    }

    pDoc->GetCoreClientStatus(status);
    if (status.task_suspend_reason & ~(SUSPEND_REASON_CPU_THROTTLE)) {
        enableShowGraphics = false;
    }

    pDoc->GetConnectedComputerName(strMachineName);
    if (!pDoc->IsComputerNameLocal(strMachineName)) {
        enableShowGraphics = false;
    }

    // Disable Show Graphics button if selected task can't display graphics
    if (!strlen(result->web_graphics_url) && !strlen(result->graphics_exec_path)) {
        enableShowGraphics = false;
    }

    if (result->suspended_via_gui ||
        result->project_suspended_via_gui || 
        (result->scheduler_state != CPU_SCHED_SCHEDULED)
    ) {
        enableShowGraphics = false;
    }
    
    m_ShowGraphicsMenuItem->Enable(enableShowGraphics);
   
    // Disable Abort button if any selected task already aborted
    if (
        result->active_task_state == PROCESS_ABORT_PENDING ||
        result->active_task_state == PROCESS_ABORTED ||
        result->state == RESULT_ABORTED 
    ) {
        enableAbort = false;
    }

    m_AbortMenuItem->Enable(enableAbort);

#ifdef __WXMAC__
    // Disable tooltips on Mac while menus are popped up because they cover menus
    wxToolTip::Enable(false);
#endif

	PopupMenu(m_TaskCommandPopUpMenu);


#if TESTBIGICONPOPUP
/*** CAF *** FOR TESTING ONLY ***/
    static int i;
    wxString s;
    
    if (i > 9) i = 0;
    if ( i < 5) {
        s = (wxT("This is a very very very and extremely long label."));
    } else {
        s = (wxT("short."));
    }
        
    switch (i++) {
        case 0:
        case 5:
            UpdateStaticText(&m_TaskProjectName, s);
            break;
        case 1:
        case 6:
            UpdateStaticText(&m_TaskApplicationName, s);
            break;
        case 2:
        case 7:
            UpdateStaticText(&m_ElapsedTimeValue, s);
            break;
        case 3:
        case 8:
            UpdateStaticText(&m_TimeRemainingValue, s);
            break;
        case 4:
        case 9:
            UpdateStaticText(&m_StatusValueText, s);
            break;
    }

	m_ProgressBar->SetValue( i * 10 ); 
    int sel = i % 3;
//    m_TaskSelectionCtrl->SetStringSelection(tempArray[sel]);
    m_TaskSelectionCtrl->SetSelection(sel);
#endif
}
示例#9
0
void TestAARHUD::UpdateHighDetailData(int baseWidth, float& curYPos)
{
   if (*mHUDState == HUDState::MAXIMUM)
   {
      char clin[HUDCONTROLMAXTEXTSIZE]; // general buffer to print
      char lastTagStr[HUDCONTROLMAXTEXTSIZE];
      char numTagsStr[HUDCONTROLMAXTEXTSIZE];
      char lastFrameStr[HUDCONTROLMAXTEXTSIZE];
      char numFramesStr[HUDCONTROLMAXTEXTSIZE];

      // Determine num tags, num frames, etc...
      if (dtGame::LogStateEnumeration::LOGGER_STATE_IDLE == mLogController->GetLastKnownStatus().GetStateEnum())
      {
         snprintf(numTagsStr, HUDCONTROLMAXTEXTSIZE, "Num Tags: NA");
         snprintf(lastTagStr, HUDCONTROLMAXTEXTSIZE, "  (Last: NA)");
         snprintf(numFramesStr, HUDCONTROLMAXTEXTSIZE, "Num Frames: NA");
         snprintf(lastFrameStr, HUDCONTROLMAXTEXTSIZE, "  (Last: NA)");
      }
      else // compute data needed for both LOGGER_STATE_PLAYBACK or LOGGER_STATE_RECORD
      {
         // TAGS - num tags and last tag
         const std::vector<dtGame::LogTag> tags = mLogController->GetLastKnownTagList();
         snprintf(numTagsStr, HUDCONTROLMAXTEXTSIZE, "Num Tags: %u", unsigned(tags.size()));
         if (tags.size() > 0)
         {
            snprintf(lastTagStr, HUDCONTROLMAXTEXTSIZE, "  (Last: None)");
            for (unsigned int i = 0; i < tags.size(); i ++)
            {
               const dtGame::LogTag tag = tags[i];
               //double tagTime = tags[i].GetSimTimeStamp();
               //double simTime = mClientGM->GetSimulationTime();

               if (tags[i].GetSimTimeStamp() <= GetGameManager()->GetSimulationTime())
               {
                  std::string temp = (tags[i]).GetName();
                  snprintf(lastTagStr, HUDCONTROLMAXTEXTSIZE, " (%s)", temp.c_str());//(tags[tags.size()-1]).GetName());
               }
            }
         }
         else
         {
            snprintf(lastTagStr, HUDCONTROLMAXTEXTSIZE, " (----)");
         }

         // FRAMES - num frames and last frame
         const std::vector<dtGame::LogKeyframe> frames = mLogController->GetLastKnownKeyframeList();
         snprintf(numFramesStr, HUDCONTROLMAXTEXTSIZE, "Num Frames: %u", unsigned(frames.size()));
         if (frames.size() > 0)
         {
            snprintf(lastFrameStr, HUDCONTROLMAXTEXTSIZE, "  (Last: None)");
            for (unsigned int i = 0; i < frames.size(); i ++)
            {
               if (frames[i].GetSimTimeStamp() <= GetGameManager()->GetSimulationTime())
               {
                  std::string temp = (frames[i]).GetName();
                  snprintf(lastFrameStr, HUDCONTROLMAXTEXTSIZE, " (%s)", temp.c_str());
               }
            }
         }
         else
         {
            snprintf(lastFrameStr, HUDCONTROLMAXTEXTSIZE, " (----)");
         }
      }

      // Num Messages
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "Num Msgs: %lu", mLogController->GetLastKnownStatus().GetNumMessages());
      curYPos += (mTextHeight + 2) * 2;
      UpdateStaticText(mNumMessagesText, clin, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Record Duration
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "Duration: %.2f", mLogController->GetLastKnownStatus().GetCurrentRecordDuration());
      curYPos += mTextHeight + 2;
      UpdateStaticText(mRecordDurationText, clin, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Number of Tags
      curYPos += mTextHeight + 2;
      UpdateStaticText(mNumTagsText, numTagsStr, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Last Tag
      curYPos += mTextHeight + 2;
      UpdateStaticText(mLastTagText, lastTagStr, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Num Frames
      curYPos += mTextHeight + 2;
      UpdateStaticText(mNumFramesText, numFramesStr, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Num Frames
      curYPos += mTextHeight + 2;
      UpdateStaticText(mLastFrameText, lastFrameStr, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Current Log
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "LogFile: %s", mLogController->GetLastKnownStatus().GetLogFile().c_str());
      curYPos += mTextHeight + 2;
      UpdateStaticText(mCurLogText, clin, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);

      // Current Map
      snprintf(clin, HUDCONTROLMAXTEXTSIZE, "CurMap: %s", mLogController->GetLastKnownStatus().GetActiveMaps()[0].c_str());
      curYPos += mTextHeight + 2;
      UpdateStaticText(mCurMapText, clin, -1.0f, -1.0f, -1.0f, baseWidth, curYPos);
   }
}