File: DashIntfScreenMsgs.cpp

package info (click to toggle)
dasher 4.11%2Bgit20130508.adc653-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 40,248 kB
  • ctags: 5,158
  • sloc: xml: 185,479; cpp: 32,301; sh: 11,207; makefile: 828; ansic: 483
file content (112 lines) | stat: -rw-r--r-- 5,407 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "DashIntfScreenMsgs.h"
#include "ScreenGameModule.h"

using namespace Dasher;

CDashIntfScreenMsgs::CDashIntfScreenMsgs(CSettingsStore *pSettingsStore)
 : CDashIntfSettings(pSettingsStore) {
}

void CDashIntfScreenMsgs::Message(const string &strText, bool bInterrupt) {
  //Just store the messages for Redraw...
  CDasherScreen::Label *lab = GetView()->Screen()->MakeLabel(strText,GetLongParameter(LP_MESSAGE_FONTSIZE));
  if (bInterrupt) {
    m_dqModalMessages.push_back(pair<CDasherScreen::Label*,bool>(lab,false));
    if (CInputFilter *fil=GetActiveInputMethod()) fil->pause();
  }
  else
    m_dqAsyncMessages.push_back(pair<CDasherScreen::Label*,unsigned long>(lab, 0));
}

bool CDashIntfScreenMsgs::FinishRender(unsigned long ulTime) {
  bool bMsgsChanged=false;
  //Finally any messages - newest that will fit at bottom, proceeding upwards.
  // Firstly clear any non-modal messages that have been onscreen for long enough
  while (!m_dqAsyncMessages.empty() && m_dqAsyncMessages.front().second && ulTime-m_dqAsyncMessages.front().second>GetLongParameter(LP_MESSAGE_TIME)) {
    delete m_dqAsyncMessages.front().first; //the Label
    m_dqAsyncMessages.pop_front(); // => stop displaying it
    bMsgsChanged=true;
  }
  CDasherScreen * const pScreen(GetView()->Screen());
  if (!m_dqAsyncMessages.empty() || !m_dqModalMessages.empty()) {
    screenint iY = pScreen->GetHeight();
    const screenint iMinY((iY*3)/4), iSW(pScreen->GetWidth());
    //still messages to display...first find out longest-ago N that will fit
    for (deque<pair<CDasherScreen::Label*, unsigned long> >::iterator it = m_dqAsyncMessages.begin(); it!=m_dqAsyncMessages.end() && iY>iMinY; it++) {
      if (it->second==0) {
        //reached a not-yet-displayed asynchronous message
        if (!m_dqModalMessages.empty()) break; //don't start displaying anything while there are modal msgs
        it->second = ulTime; //display message for first time
        bMsgsChanged=true;
      } 
      iY-=pScreen->TextSize(it->first, GetLongParameter(LP_MESSAGE_FONTSIZE)).second;
    }
    if (!m_dqModalMessages.empty()) {
      bool bDisp(m_dqModalMessages.front().second != 0); //displaying anything atm?
      for (deque<pair<CDasherScreen::Label*,unsigned long> >::iterator it=m_dqModalMessages.begin(); it!=m_dqModalMessages.end() && iY>iMinY; it++) {
        if (bDisp) {
          if (it->second==0) break; //don't start displaying more until previous dismissed
        } else {
          DASHER_ASSERT(it->second==0);
          it->second = ulTime;
          bMsgsChanged = true;
        }
        iY-=pScreen->TextSize(it->first, GetLongParameter(LP_MESSAGE_FONTSIZE)).second;
      }
    }
    //Now render messages proceeding downwards - non-modal first, then oldest first
    bool bModal(false);
    for (deque<pair<CDasherScreen::Label*, unsigned long> >::const_iterator it = m_dqAsyncMessages.begin(); it != m_dqAsyncMessages.end(); it++) {
      if (it->second==0) continue;
      pair<screenint,screenint> textDims = pScreen->TextSize(it->first, GetLongParameter(LP_MESSAGE_FONTSIZE));
      //black (5) rectangle:
      pScreen->DrawRectangle((iSW - textDims.first)/2, iY, (iSW+textDims.first)/2, iY+textDims.second, 5, -1, -1);
      //white (0) text for non-modal, yellow (111) for modal
      pScreen->DrawString(it->first, (iSW-textDims.first)/2, iY, GetLongParameter(LP_MESSAGE_FONTSIZE), bModal ? 111 : 0);
      iY+=textDims.second;
    }
    bModal=true;
    for (deque<pair<CDasherScreen::Label*, unsigned long> >::const_iterator it = m_dqModalMessages.begin(); it != m_dqModalMessages.end(); it++) {
      if (it->second==0) continue;
      pair<screenint,screenint> textDims = pScreen->TextSize(it->first, GetLongParameter(LP_MESSAGE_FONTSIZE));
      //black (5) rectangle:
      pScreen->DrawRectangle((iSW - textDims.first)/2, iY, (iSW+textDims.first)/2, iY+textDims.second, 5, -1, -1);
      //white (0) text for non-modal, yellow (111) for modal
      pScreen->DrawString(it->first, (iSW-textDims.first)/2, iY, GetLongParameter(LP_MESSAGE_FONTSIZE), bModal ? 111 : 0);
      iY+=textDims.second;
    }
  }
  return bMsgsChanged;
}

void CDashIntfScreenMsgs::ChangeScreen(CDasherScreen *pNewScreen) {
  CDasherInterfaceBase::ChangeScreen(pNewScreen);
  for (deque<pair<CDasherScreen::Label*,unsigned long> >::iterator it=m_dqAsyncMessages.begin(); ; it++) {
    if (it==m_dqAsyncMessages.end()) it = m_dqModalMessages.begin();
    if (it==m_dqModalMessages.end()) break;
    const CDasherScreen::Label *pOldLabel(it->first);
    it->first = pNewScreen->MakeLabel(pOldLabel->m_strText, pOldLabel->m_iWrapSize);
    delete pOldLabel;
  }
}

void CDashIntfScreenMsgs::onUnpause(unsigned long lTime) {
  while (!m_dqModalMessages.empty()) {
    if (m_dqModalMessages.front().second) {
      //Message has been displayed; delete it
      delete m_dqModalMessages.front().first; //the label
      m_dqModalMessages.pop_front();
    } else {
      //there are more, not-yet displayed, modal messages!
      //These should be after any that were displayed (which have now been erased),
      // so do not unpause; next frame will render more messages instead.
      GetActiveInputMethod()->pause();
      return;
    }
  }
  CDasherInterfaceBase::onUnpause(lTime);
}

CGameModule *CDashIntfScreenMsgs::CreateGameModule() {
  return new CScreenGameModule(this, this, GetView(), m_pDasherModel);
}