DialogsManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. #include "core/DialogsManager.h"
  2. #include "core/ConfigVar.h"
  3. #include "core/DebugDraw.h"
  4. #include "core/Logger.h"
  5. #include "core/TextManager.h"
  6. template<>DialogsManager *Ogre::Singleton< DialogsManager >::msSingleton = NULL;
  7. ConfigVar cv_debug_message( "debug_message", "Draw message debug", "false" );
  8. Ogre::String message_state_string[ 5 ] = {"Closed", "Show Window", "Show Text", "Opened", "Hide Window"};
  9. DialogsManager::DialogsManager():
  10. m_NextPressed( false ),
  11. m_NextRepeated( false ),
  12. m_UpPressed( false ),
  13. m_DownPressed( false ),
  14. m_LimitArea( NULL )
  15. {
  16. LOG_TRIVIAL( "DialogsManager created." );
  17. }
  18. DialogsManager::~DialogsManager()
  19. {
  20. for( unsigned int i = 0; i < m_Messages.size(); ++i )
  21. {
  22. delete m_Messages[ i ];
  23. }
  24. LOG_TRIVIAL( "DialogsManager destroyed." );
  25. }
  26. void
  27. DialogsManager::Initialise()
  28. {
  29. UiWidget* g_widget = UiManager::getSingletonPtr()->GetWidget( "Dialog" );
  30. if( g_widget == NULL )
  31. {
  32. LOG_ERROR( "Can't create DialogsManager because Widget \"Dialog\" not founded." );
  33. return;
  34. }
  35. m_LimitArea = g_widget->GetChild( "LimitArea" );
  36. if( m_LimitArea == NULL )
  37. {
  38. LOG_ERROR( "Can't create DialogsManager because Widget \"LimitArea\" not founded in Widget \"Dialog\"." );
  39. return;
  40. }
  41. unsigned int num = m_LimitArea->GetNumberOfChildren();
  42. for( unsigned int i = 0; i < num; ++i )
  43. {
  44. UiWidget* widget = m_LimitArea->GetChild( i );
  45. UiTextArea* text_area = (UiTextArea*) widget->GetChild( "TextArea" );
  46. if( text_area == NULL )
  47. {
  48. LOG_ERROR( "Can't create dialog \"" +widget->GetName() + "\" because because text_area with name \"TextArea\" missing." );
  49. continue;
  50. }
  51. MessageData* data = new MessageData();
  52. data->widget = widget;
  53. data->window = widget->GetChild( "Window" );
  54. data->text_area = text_area;
  55. data->text_area->SetTextPrintSpeed( 256 );
  56. data->text_area->SetTextScrollTime( 0.267f );
  57. data->cursor = widget->GetChild( "Cursor" );
  58. if( data->cursor != NULL )
  59. {
  60. data->cursor->GetY( data->cursor_percent_y, data->cursor_y );
  61. }
  62. m_Messages.push_back( data );
  63. }
  64. LOG_TRIVIAL( "DialogsManager initialized." );
  65. }
  66. void
  67. DialogsManager::Input( const QGears::Event& input )
  68. {
  69. if ((input.type == QGears::ET_KEY_PRESS) && (input.event == "message_ok"))
  70. {
  71. m_NextPressed = true;
  72. }
  73. else if ((input.type == QGears::ET_KEY_REPEAT) && (input.event == "message_ok"))
  74. {
  75. m_NextRepeated = true;
  76. }
  77. else if ((input.type == QGears::ET_KEY_PRESS) && (input.event == "message_up"))
  78. {
  79. m_UpPressed = true;
  80. }
  81. else if ((input.type == QGears::ET_KEY_PRESS) && (input.event == "message_down"))
  82. {
  83. m_DownPressed = true;
  84. }
  85. }
  86. void
  87. DialogsManager::Update()
  88. {
  89. for( unsigned int i = 0; i < m_Messages.size(); ++i )
  90. {
  91. switch( m_Messages[ i ]->state )
  92. {
  93. case MS_SHOW_WINDOW:
  94. {
  95. if( ( m_Messages[ i ]->window == NULL ) || (m_Messages[ i ]->window->GetCurrentAnimationName() == Ogre::StringUtil::BLANK ) )
  96. {
  97. m_Messages[ i ]->text_area->PlayAnimation( "Show", UiAnimation::ONCE, 0, -1 );
  98. m_Messages[ i ]->text_area->SetVisible( true );
  99. m_Messages[ i ]->state = MS_SHOW_TEXT;
  100. }
  101. }
  102. break;
  103. case MS_SHOW_TEXT:
  104. {
  105. if( AutoCloseCheck( i ) == true )
  106. {
  107. break;
  108. }
  109. if( m_Messages[ i ]->clickable == true )
  110. {
  111. if( m_NextPressed == true )
  112. {
  113. m_Messages[ i ]->text_area->InputPressed();
  114. }
  115. if( m_NextRepeated == true )
  116. {
  117. m_Messages[ i ]->text_area->InputRepeated();
  118. }
  119. }
  120. if( m_Messages[ i ]->text_area->GetTextState() == TS_DONE )
  121. {
  122. m_Messages[ i ]->state = MS_OPENED;
  123. if( ( m_Messages[ i ]->cursor != NULL ) && ( m_Messages[ i ]->show_cursor == true ) )
  124. {
  125. m_Messages[ i ]->cursor->SetY( m_Messages[ i ]->cursor_percent_y, m_Messages[ i ]->cursor_y + m_Messages[ i ]->cursor_row_current * m_Messages[ i ]->text_area->GetFont()->GetHeight() );
  126. m_Messages[ i ]->cursor->SetVisible( true );
  127. }
  128. }
  129. }
  130. break;
  131. case MS_OPENED:
  132. {
  133. if( m_Messages[ i ]->clickable == true && m_NextPressed == true )
  134. {
  135. m_Messages[ i ]->auto_close = true;
  136. if( ( m_Messages[ i ]->cursor != NULL ) && ( m_Messages[ i ]->show_cursor == true ) )
  137. {
  138. m_Messages[ i ]->show_cursor = false;
  139. m_Messages[ i ]->cursor_row_selected = m_Messages[ i ]->cursor_row_current;
  140. m_Messages[ i ]->cursor->SetVisible( false );
  141. }
  142. }
  143. if( AutoCloseCheck( i ) == true )
  144. {
  145. break;
  146. }
  147. if( ( m_Messages[ i ]->cursor != NULL ) && ( m_Messages[ i ]->show_cursor == true ) && ( m_Messages[ i ]->clickable == true ) )
  148. {
  149. if( m_UpPressed == true )
  150. {
  151. m_Messages[ i ]->cursor_row_current -= 1;
  152. }
  153. else if( m_DownPressed == true )
  154. {
  155. m_Messages[ i ]->cursor_row_current += 1;
  156. }
  157. m_Messages[ i ]->cursor_row_current = ( m_Messages[ i ]->cursor_row_current < m_Messages[ i ]->cursor_row_first ) ? m_Messages[ i ]->cursor_row_last : m_Messages[ i ]->cursor_row_current;
  158. m_Messages[ i ]->cursor_row_current = ( m_Messages[ i ]->cursor_row_current > m_Messages[ i ]->cursor_row_last ) ? m_Messages[ i ]->cursor_row_first : m_Messages[ i ]->cursor_row_current;
  159. m_Messages[ i ]->cursor->SetY( m_Messages[ i ]->cursor_percent_y, m_Messages[ i ]->cursor_y + m_Messages[ i ]->cursor_row_current * m_Messages[ i ]->text_area->GetFont()->GetHeight() );
  160. }
  161. }
  162. break;
  163. case MS_HIDE_WINDOW:
  164. {
  165. if( ( m_Messages[ i ]->window == NULL ) || (m_Messages[ i ]->window->GetCurrentAnimationName() == Ogre::StringUtil::BLANK ) )
  166. {
  167. HideMessage( i );
  168. }
  169. }
  170. break;
  171. }
  172. }
  173. if( cv_debug_message.GetB() == true )
  174. {
  175. DEBUG_DRAW.SetColour( Ogre::ColourValue::White );
  176. DEBUG_DRAW.SetTextAlignment( DEBUG_DRAW.LEFT );
  177. DEBUG_DRAW.SetScreenSpace( true );
  178. int y = 34;
  179. for( unsigned int i = 0; i < m_Messages.size(); ++i )
  180. {
  181. Ogre::String caption;
  182. caption += "Message " + Ogre::StringConverter::toString( i ) + ": " + message_state_string[ m_Messages[ i ]->state ];
  183. if( m_Messages[ i ]->state == MS_SHOW_TEXT )
  184. {
  185. caption += " (" + Ogre::StringConverter::toString( int( m_Messages[ i ]->text_area->GetTextLimit() ) ) + "/" + Ogre::StringConverter::toString( m_Messages[ i ]->text_area->GetTextSize() );
  186. switch( m_Messages[ i ]->text_area->GetTextState() )
  187. {
  188. case TS_PAUSE_OK: caption += " pause ok"; break;
  189. case TS_PAUSE_TIME: caption += " pause time " + Ogre::StringConverter::toString( int( m_Messages[ i ]->text_area->GetPauseTime() ) ); break;
  190. case TS_OVERFLOW: caption += " overflow"; break;
  191. case TS_NEXT_PAGE: caption += " next page"; break;
  192. case TS_SCROLL_TEXT: caption += " scroll"; break;
  193. }
  194. caption += ")";
  195. }
  196. DEBUG_DRAW.Text( 10, y, caption );
  197. y += 16;
  198. }
  199. }
  200. m_NextPressed = false;
  201. m_NextRepeated = false;
  202. m_UpPressed = false;
  203. m_DownPressed = false;
  204. }
  205. void
  206. DialogsManager::Clear()
  207. {
  208. for( unsigned int i = 0; i < m_Messages.size(); ++i )
  209. {
  210. HideMessage( i );
  211. }
  212. }
  213. void
  214. DialogsManager::OpenDialog(const char* d_name, int x, int y, int w, int h)
  215. {
  216. int id = GetMessageId( d_name );
  217. if( id == -1 )
  218. {
  219. LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  220. return;
  221. }
  222. MessageData* data = m_Messages[id];
  223. if( data->state != MS_CLOSED )
  224. {
  225. LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog \"" + Ogre::String( d_name ) + " already created. Close it first." );
  226. return;
  227. }
  228. data->x = x;
  229. data->y = y;
  230. data->w = w;
  231. data->h = h;
  232. LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog(" +
  233. std::to_string(x) + "," + std::to_string(y) + "," +
  234. std::to_string(w) + "," + std::to_string(h) + ")");
  235. }
  236. void
  237. DialogsManager::SetText(const char* d_name, const char* text)
  238. {
  239. int id = GetMessageId(d_name);
  240. if (id == -1)
  241. {
  242. LOG_TRIVIAL("[SCRIPT] show_text: dialog \"" + Ogre::String(d_name) + "\" doesn't exist.");
  243. return;
  244. }
  245. MessageData* data = m_Messages[id];
  246. // XML data can change dialog w/h VS whats in the lua script
  247. float width = 0.0f;
  248. float height = 0.0f;
  249. TiXmlNode* xmlText = TextManager::getSingleton().GetDialog(text, width, height);
  250. if (xmlText != NULL)
  251. {
  252. m_Messages[id]->text_area->SetText(xmlText);
  253. ShowMessage(id, data->x, data->y,
  254. width == 0.0f ? data->w : width,
  255. height == 0.0f ? data->h : height);
  256. }
  257. else
  258. {
  259. m_Messages[id]->text_area->SetText(std::string("[ERROR string not found:] ") + text);
  260. ShowMessage(id, data->x, data->y, data->w, data->h);
  261. }
  262. }
  263. int
  264. DialogsManager::Sync( const char* d_name )
  265. {
  266. int id = GetMessageId( d_name );
  267. if( id == -1 )
  268. {
  269. LOG_TRIVIAL( "[SCRIPT] sync: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  270. return 1;
  271. }
  272. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  273. m_Messages[ id ]->sync.push_back( script );
  274. return -1;
  275. }
  276. void
  277. DialogsManager::Hide( const char* d_name )
  278. {
  279. int id = GetMessageId( d_name );
  280. if( id == -1 )
  281. {
  282. LOG_TRIVIAL( "[SCRIPT] hide: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  283. return;
  284. }
  285. if( m_Messages[ id ]->state == MS_CLOSED )
  286. {
  287. LOG_TRIVIAL( "[SCRIPT ERROR] hide: dialog \"" + Ogre::String( d_name ) + "\" already closed. Open it first." );
  288. return;
  289. }
  290. m_Messages[ id ]->auto_close = true;
  291. }
  292. void
  293. DialogsManager::SetVariable(const char* d_name, const char* name, const char* value)
  294. {
  295. int id = GetMessageId(d_name);
  296. if (id == -1)
  297. {
  298. LOG_TRIVIAL("[SCRIPT] set_variable: dialog \"" + Ogre::String(d_name) + "\" doesn't exist.");
  299. return;
  300. }
  301. m_Messages[id]->text_area->SetVariable(name, value);
  302. }
  303. void
  304. DialogsManager::SetClickable( const char* d_name, const bool clickable )
  305. {
  306. int id = GetMessageId( d_name );
  307. if( id == -1 )
  308. {
  309. LOG_TRIVIAL( "[SCRIPT] set_clickable: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  310. return;
  311. }
  312. m_Messages[ id ]->clickable = clickable;
  313. }
  314. void
  315. DialogsManager::SetCursor( const char* d_name, const int first_row, const int last_row )
  316. {
  317. int id = GetMessageId( d_name );
  318. if( id == -1 )
  319. {
  320. LOG_TRIVIAL( "[SCRIPT] set_cursor: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  321. return;
  322. }
  323. if( m_Messages[ id ]->state != MS_CLOSED )
  324. {
  325. LOG_TRIVIAL( "[SCRIPT] set_cursor: dialog \"" + Ogre::String( d_name ) + "\" already shown. Close it first." );
  326. return;
  327. }
  328. m_Messages[ id ]->show_cursor = true;
  329. m_Messages[ id ]->cursor_row_current = first_row;
  330. m_Messages[ id ]->cursor_row_first = first_row;
  331. m_Messages[ id ]->cursor_row_last = last_row;
  332. }
  333. int
  334. DialogsManager::GetCursor( const char* d_name ) const
  335. {
  336. int id = GetMessageId( d_name );
  337. if( id == -1 )
  338. {
  339. LOG_TRIVIAL( "[SCRIPT] get_cursor: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
  340. return 0;
  341. }
  342. return m_Messages[ id ]->cursor_row_selected;
  343. }
  344. void
  345. DialogsManager::ShowMessage( const int id, const int x, const int y, const int width, const int height )
  346. {
  347. // handle error when dialog wingow cross border of limit area
  348. float la_percent_width, la_width;
  349. m_LimitArea->GetWidth( la_percent_width, la_width );
  350. float move_back_x = 0;
  351. if( x + width > la_width )
  352. {
  353. move_back_x = x + width - la_width;
  354. }
  355. float la_percent_height, la_height;
  356. m_LimitArea->GetWidth( la_percent_height, la_height );
  357. float move_back_y = 0;
  358. if( y + height > la_height )
  359. {
  360. move_back_y = y + height - la_height;
  361. }
  362. m_Messages[ id ]->widget->SetX( 0, x - move_back_x );
  363. m_Messages[ id ]->widget->SetY( 0, y - move_back_y );
  364. m_Messages[ id ]->widget->SetWidth( 0, width );
  365. m_Messages[ id ]->widget->SetHeight( 0, height );
  366. m_Messages[ id ]->widget->SetVisible( true );
  367. m_Messages[ id ]->auto_close = false;
  368. if( ( m_Messages[ id ]->window != NULL ) && ( m_Messages[ id ]->show_window == true ) )
  369. {
  370. m_Messages[ id ]->window->SetVisible( true );
  371. m_Messages[ id ]->window->PlayAnimation( "Show", UiAnimation::ONCE, 0, -1 );
  372. }
  373. m_Messages[ id ]->state = MS_SHOW_WINDOW;
  374. }
  375. void
  376. DialogsManager::HideMessage( const int id )
  377. {
  378. m_Messages[ id ]->auto_close = false;
  379. m_Messages[ id ]->state = MS_CLOSED;
  380. if( m_Messages[ id ]->window != NULL )
  381. {
  382. m_Messages[ id ]->window->SetVisible( false );
  383. }
  384. if( m_Messages[ id ]->cursor != NULL )
  385. {
  386. m_Messages[ id ]->cursor->SetVisible( false );
  387. }
  388. m_Messages[ id ]->text_area->SetVisible( false );
  389. m_Messages[ id ]->widget->SetVisible( false );
  390. for( unsigned int i = 0; i < m_Messages[ id ]->sync.size(); ++i )
  391. {
  392. ScriptManager::getSingleton().ContinueScriptExecution( m_Messages[ id ]->sync[ i ] );
  393. }
  394. m_Messages[ id ]->sync.clear();
  395. }
  396. int
  397. DialogsManager::GetMessageId( const char* d_name ) const
  398. {
  399. for( unsigned int i = 0; i < m_Messages.size(); ++i )
  400. {
  401. if( m_Messages[ i ]->widget->GetName() == Ogre::String( d_name ) )
  402. {
  403. return i;
  404. }
  405. }
  406. return -1;
  407. }
  408. bool
  409. DialogsManager::AutoCloseCheck( const unsigned int id )
  410. {
  411. if( m_Messages[ id ]->auto_close == true )
  412. {
  413. m_Messages[ id ]->text_area->PlayAnimation( "Hide", UiAnimation::ONCE, 0, -1 );
  414. if( m_Messages[ id ]->window != NULL )
  415. {
  416. m_Messages[ id ]->window->PlayAnimation( "Hide", UiAnimation::ONCE, 0, -1 );
  417. }
  418. m_Messages[ id ]->state = MS_HIDE_WINDOW;
  419. return true;
  420. }
  421. return false;
  422. }