callbacks_gui.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. #include "callbacks_gui.h"
  2. #include <QCoreApplication>
  3. #include <QThread>
  4. #include <QElapsedTimer>
  5. #include <QFileInfo>
  6. #include <QFileDialog>
  7. #include <QInputDialog>
  8. #include <QLineEdit>
  9. #include <QTimer>
  10. #include <QEventLoop>
  11. #include "comtools.h"
  12. #include "qspmsgdlg.h"
  13. #include "qspinputdlg.h"
  14. #ifdef _WEBBOX
  15. #include "qspwebbox.h"
  16. #endif
  17. #ifdef _WEBBOX_WEBKIT
  18. #include "qspwebbox_webkit.h"
  19. #endif
  20. QString QSPCallBacks::m_gamePath;
  21. MainWindow *QSPCallBacks::m_frame;
  22. bool QSPCallBacks::m_isHtml;
  23. QSPSounds QSPCallBacks::m_sounds;
  24. float QSPCallBacks::m_volumeCoeff;
  25. bool QSPCallBacks::m_isAllowHTML5Extras;
  26. void QSPCallBacks::Init(MainWindow *frame)
  27. {
  28. m_frame = frame;
  29. m_volumeCoeff = 1.0f;
  30. m_isAllowHTML5Extras = false;
  31. QSPSetCallBack(QSP_CALL_SETTIMER, (QSP_CALLBACK)&SetTimer);
  32. QSPSetCallBack(QSP_CALL_REFRESHINT, (QSP_CALLBACK)&RefreshInt);
  33. QSPSetCallBack(QSP_CALL_SETINPUTSTRTEXT, (QSP_CALLBACK)&SetInputStrText);
  34. QSPSetCallBack(QSP_CALL_ISPLAYINGFILE, (QSP_CALLBACK)&IsPlay);
  35. QSPSetCallBack(QSP_CALL_PLAYFILE, (QSP_CALLBACK)&PlayFile);
  36. QSPSetCallBack(QSP_CALL_CLOSEFILE, (QSP_CALLBACK)&CloseFile);
  37. QSPSetCallBack(QSP_CALL_SHOWMSGSTR, (QSP_CALLBACK)&Msg);
  38. QSPSetCallBack(QSP_CALL_SLEEP, (QSP_CALLBACK)&Sleep);
  39. QSPSetCallBack(QSP_CALL_GETMSCOUNT, (QSP_CALLBACK)&GetMSCount);
  40. QSPSetCallBack(QSP_CALL_DELETEMENU, (QSP_CALLBACK)&DeleteMenu);
  41. QSPSetCallBack(QSP_CALL_ADDMENUITEM, (QSP_CALLBACK)&AddMenuItem);
  42. QSPSetCallBack(QSP_CALL_SHOWMENU, (QSP_CALLBACK)&ShowMenu);
  43. QSPSetCallBack(QSP_CALL_INPUTBOX, (QSP_CALLBACK)&Input);
  44. QSPSetCallBack(QSP_CALL_SHOWIMAGE, (QSP_CALLBACK)&ShowImage);
  45. QSPSetCallBack(QSP_CALL_SHOWWINDOW, (QSP_CALLBACK)&ShowPane);
  46. //QSPSetCallBack(QSP_CALL_OPENGAME, (QSP_CALLBACK)&OpenGame); //replace
  47. QSPSetCallBack(QSP_CALL_OPENGAMESTATUS, (QSP_CALLBACK)&OpenGameStatus);
  48. QSPSetCallBack(QSP_CALL_SAVEGAMESTATUS, (QSP_CALLBACK)&SaveGameStatus);
  49. //TODO: implement this?
  50. //QSP_CALL_DEBUG, /* void func(QSPString str) */
  51. }
  52. void QSPCallBacks::DeInit()
  53. {
  54. CloseFile(0);
  55. }
  56. void QSPCallBacks::SetTimer(int msecs)
  57. {
  58. if (m_frame->IsQuit()) return;
  59. if (msecs)
  60. m_frame->GetTimer()->start(msecs);
  61. else
  62. m_frame->GetTimer()->stop();
  63. }
  64. void QSPCallBacks::RefreshInt(QSP_BOOL isRedraw)
  65. {
  66. static int oldFullRefreshCount = 0;
  67. int i, numVal;
  68. bool isScroll, isCanSave;
  69. QSP_CHAR *strVal, *imgPath;
  70. if (m_frame->IsQuit()) return;
  71. // -------------------------------
  72. UpdateGamePath();
  73. // -------------------------------
  74. const QSP_CHAR *mainDesc = QSPGetMainDesc();
  75. const QSP_CHAR *varsDesc = QSPGetVarsDesc();
  76. // -------------------------------
  77. isScroll = !(QSPGetVarValues(QSP_FMT("DISABLESCROLL"), 0, &numVal, &strVal) && numVal);
  78. isCanSave = !(QSPGetVarValues(QSP_FMT("NOSAVE"), 0, &numVal, &strVal) && numVal);
  79. m_isHtml = QSPGetVarValues(QSP_FMT("USEHTML"), 0, &numVal, &strVal) && numVal;
  80. // -------------------------------
  81. m_frame->GetVars()->SetIsHtml(m_isHtml);
  82. if (QSPIsVarsDescChanged())
  83. {
  84. m_frame->EnableControls(false, true);
  85. if(m_isAllowHTML5Extras)
  86. {
  87. if (QSPGetVarValues(QSP_FMT("SETSTATHEAD"), 0, &numVal, &strVal) && strVal)
  88. m_frame->GetVars()->SetHead(QSPTools::qspStrToQt(strVal));
  89. else
  90. m_frame->GetVars()->SetHead(QString(""));
  91. }
  92. m_frame->GetVars()->SetText(QSPTools::qspStrToQt(varsDesc), isScroll);
  93. m_frame->EnableControls(true, true);
  94. }
  95. // -------------------------------
  96. int fullRefreshCount = QSPGetFullRefreshCount();
  97. if (oldFullRefreshCount != fullRefreshCount)
  98. {
  99. isScroll = false;
  100. oldFullRefreshCount = fullRefreshCount;
  101. }
  102. m_frame->GetDesc()->SetIsHtml(m_isHtml);
  103. if (QSPIsMainDescChanged())
  104. {
  105. m_frame->EnableControls(false, true);
  106. if(m_isAllowHTML5Extras)
  107. {
  108. if (QSPGetVarValues(QSP_FMT("SETMAINDESCHEAD"), 0, &numVal, &strVal) && strVal)
  109. m_frame->GetDesc()->SetHead(QSPTools::qspStrToQt(strVal));
  110. else
  111. m_frame->GetDesc()->SetHead(QString(""));
  112. }
  113. m_frame->GetDesc()->SetText(QSPTools::qspStrToQt(mainDesc), isScroll);
  114. m_frame->EnableControls(true, true);
  115. }
  116. // -------------------------------
  117. m_frame->GetActions()->SetIsHtml(m_isHtml);
  118. m_frame->GetActions()->SetIsShowNums(m_frame->IsShowHotkeys());
  119. if (QSPIsActionsChanged())
  120. {
  121. int actionsCount = QSPGetActionsCount();
  122. m_frame->GetActions()->BeginItems();
  123. for (i = 0; i < actionsCount; ++i)
  124. {
  125. QSPGetActionData(i, &imgPath, &strVal);
  126. m_frame->GetActions()->AddItem(QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(imgPath)), QSPTools::qspStrToQt(strVal));
  127. }
  128. m_frame->GetActions()->EndItems();
  129. }
  130. m_frame->GetActions()->SetSelection(QSPGetSelActionIndex());
  131. m_frame->GetObjects()->SetIsHtml(m_isHtml);
  132. if (QSPIsObjectsChanged())
  133. {
  134. int objectsCount = QSPGetObjectsCount();
  135. m_frame->GetObjects()->BeginItems();
  136. for (i = 0; i < objectsCount; ++i)
  137. {
  138. QSPGetObjectData(i, &imgPath, &strVal);
  139. m_frame->GetObjects()->AddItem(QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(imgPath)), QSPTools::qspStrToQt(strVal));
  140. }
  141. m_frame->GetObjects()->EndItems();
  142. }
  143. m_frame->GetObjects()->SetSelection(QSPGetSelObjectIndex());
  144. // -------------------------------
  145. if (QSPGetVarValues(QSP_FMT("BACKIMAGE"), 0, &numVal, &strVal) && strVal)
  146. m_frame->GetDesc()->LoadBackImage(QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(strVal)));
  147. else
  148. m_frame->GetDesc()->LoadBackImage(QString(""));
  149. // -------------------------------
  150. m_frame->ApplyParams();
  151. if (isRedraw)
  152. {
  153. m_frame->EnableControls(false, true);
  154. //m_frame->Update();
  155. //QCoreApplication::processEvents();
  156. if (m_frame->IsQuit()) return;
  157. m_frame->EnableControls(true, true);
  158. }
  159. m_frame->GetGameMenu()->setEnabled(isCanSave);
  160. }
  161. void QSPCallBacks::SetInputStrText(const QSP_CHAR *text)
  162. {
  163. if (m_frame->IsQuit()) return;
  164. m_frame->GetInput()->SetText(QSPTools::qspStrToQt(text));
  165. }
  166. QSP_BOOL QSPCallBacks::IsPlay(const QSP_CHAR *file)
  167. {
  168. QSP_BOOL playing = QSP_FALSE;
  169. QSPSounds::iterator elem = m_sounds.find(QFileInfo(m_gamePath + QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(file))).absoluteFilePath());
  170. if (elem != m_sounds.end())
  171. if(elem.value()->state() == QMediaPlayer::PlayingState)
  172. playing = QSP_TRUE;
  173. return playing;
  174. }
  175. void QSPCallBacks::CloseFile(const QSP_CHAR *file)
  176. {
  177. if (file)
  178. {
  179. QSPSounds::iterator elem = m_sounds.find(QFileInfo(m_gamePath + QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(file))).absoluteFilePath());
  180. if (elem != m_sounds.end())
  181. {
  182. delete elem.value();
  183. m_sounds.erase(elem);
  184. }
  185. }
  186. else
  187. {
  188. for (QSPSounds::iterator i = m_sounds.begin(); i != m_sounds.end(); ++i)
  189. delete i.value();
  190. m_sounds.clear();
  191. }
  192. }
  193. void QSPCallBacks::PlayFile(const QSP_CHAR *file, int volume)
  194. {
  195. if (SetVolume(file, volume)) return;
  196. CloseFile(file);
  197. QString strFile(QFileInfo(m_gamePath + QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(file))).absoluteFilePath());
  198. QMediaPlayer *snd = new QMediaPlayer();
  199. snd->setMedia(QUrl::fromLocalFile(strFile));
  200. snd->setVolume(volume*m_volumeCoeff);
  201. snd->play();
  202. m_sounds.insert(strFile, snd);
  203. UpdateSounds();
  204. }
  205. void QSPCallBacks::ShowPane(int type, QSP_BOOL isShow)
  206. {
  207. if (m_frame->IsQuit()) return;
  208. switch (type)
  209. {
  210. case QSP_WIN_ACTS:
  211. m_frame->GetActionsDock()->setVisible(isShow != QSP_FALSE);
  212. break;
  213. case QSP_WIN_OBJS:
  214. m_frame->GetObjectsDock()->setVisible(isShow != QSP_FALSE);
  215. break;
  216. case QSP_WIN_VARS:
  217. m_frame->GetVarsDock()->setVisible(isShow != QSP_FALSE);
  218. break;
  219. case QSP_WIN_INPUT:
  220. m_frame->GetInputDock()->setVisible(isShow != QSP_FALSE);
  221. break;
  222. }
  223. }
  224. void QSPCallBacks::Sleep(int msecs)
  225. {
  226. QTimer wtimer;
  227. wtimer.setSingleShot(true);
  228. QEventLoop loop;
  229. QObject::connect(&wtimer, SIGNAL(timeout()), &loop, SLOT(quit()));
  230. wtimer.start(50);
  231. loop.exec();
  232. //RefreshInt(QSP_TRUE);
  233. if (m_frame->IsQuit()) return;
  234. bool isSave = m_frame->GetGameMenu()->isEnabled();
  235. bool isBreak = false;
  236. m_frame->EnableControls(false, true);
  237. int i, count = msecs / 50;
  238. for (i = 0; i < count; ++i)
  239. {
  240. //QThread::msleep(50);
  241. wtimer.start(50);
  242. loop.exec();
  243. //qDebug() << QSPTools::qspStrToQt(QSPGetMainDesc());
  244. //m_frame->Update();
  245. //QCoreApplication::processEvents();
  246. if (m_frame->IsQuit() ||
  247. m_frame->IsKeyPressedWhileDisabled()) //TODO: implement
  248. {
  249. isBreak = true;
  250. break;
  251. }
  252. }
  253. if (!isBreak) //NOTE: no check in old code
  254. {
  255. //QThread::msleep(msecs % 50);
  256. wtimer.start(msecs % 50);
  257. loop.exec();
  258. //m_frame->Update();
  259. //QCoreApplication::processEvents();
  260. }
  261. m_frame->EnableControls(true, true);
  262. m_frame->GetGameMenu()->setEnabled(isSave);
  263. }
  264. int QSPCallBacks::GetMSCount()
  265. {
  266. static QElapsedTimer stopWatch;
  267. if(stopWatch.isValid() == false)
  268. stopWatch.start();
  269. int ret = stopWatch.restart();
  270. return ret;
  271. }
  272. void QSPCallBacks::Msg(const QSP_CHAR *str)
  273. {
  274. if (m_frame->IsQuit()) return;
  275. RefreshInt(QSP_FALSE);
  276. QspMsgDlg dialog(m_frame->GetDesc()->GetBackgroundColor(),
  277. m_frame->GetDesc()->GetForegroundColor(),
  278. m_frame->GetDesc()->GetTextFont(),
  279. MainWindow::tr("Info"), //caption
  280. QSPTools::qspStrToQt(str),
  281. m_isHtml,
  282. m_gamePath,
  283. m_frame
  284. );
  285. m_frame->EnableControls(false);
  286. dialog.exec();
  287. m_frame->EnableControls(true);
  288. }
  289. void QSPCallBacks::DeleteMenu()
  290. {
  291. if (m_frame->IsQuit()) return;
  292. m_frame->DeleteMenu();
  293. }
  294. void QSPCallBacks::AddMenuItem(const QSP_CHAR *name, const QSP_CHAR *imgPath)
  295. {
  296. if (m_frame->IsQuit()) return;
  297. m_frame->AddMenuItem(QSPTools::qspStrToQt(name), QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(imgPath)));
  298. }
  299. int QSPCallBacks::ShowMenu()
  300. {
  301. if (m_frame->IsQuit()) return -1;
  302. m_frame->EnableControls(false);
  303. int index = m_frame->ShowMenu();
  304. m_frame->EnableControls(true);
  305. return index;
  306. }
  307. void QSPCallBacks::Input(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen)
  308. {
  309. if (m_frame->IsQuit()) return;
  310. RefreshInt(QSP_FALSE);
  311. // QSPInputDlg dialog(m_frame,
  312. // wxID_ANY,
  313. // m_frame->GetDesc()->GetBackgroundColor(),
  314. // m_frame->GetDesc()->GetForegroundColor(),
  315. // m_frame->GetDesc()->GetTextFont(),
  316. // _("Input data"),
  317. // wxString(text.Str, text.End),
  318. // m_isHtml,
  319. // m_gamePath
  320. // );
  321. // m_frame->EnableControls(false);
  322. // dialog.ShowModal();
  323. // m_frame->EnableControls(true);
  324. // #ifdef _UNICODE
  325. // wcsncpy(buffer, dialog.GetText().c_str(), maxLen);
  326. // #else
  327. // strncpy(buffer, dialog.GetText().c_str(), maxLen);
  328. // #endif
  329. //QString inputText = QInputDialog::getMultiLineText(m_frame, MainWindow::tr("Input data"), QSPTools::qspStrToQt(text));
  330. QString inputText = QInputDialog::getText(m_frame, MainWindow::tr("Input data"), QSPTools::qspStrToQt(text), QLineEdit::Normal);
  331. c16sncpy(buffer, (QSP_CHAR *)(inputText.utf16()), maxLen);
  332. }
  333. void QSPCallBacks::ShowImage(const QSP_CHAR *file)
  334. {
  335. if (m_frame->IsQuit()) return;
  336. m_frame->GetImgView()->OpenFile(QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(file))); //NOTE: will not display image if file is not found
  337. if(QSPTools::qspStrToQt(file) == "")
  338. {
  339. m_frame->GetImageDock()->setVisible(false);
  340. }
  341. else
  342. {
  343. m_frame->GetImageDock()->setVisible(true);
  344. }
  345. //m_frame->GetImgView()->setVisible(true);
  346. }
  347. //void QSPCallBacks::OpenGame(const QSP_CHAR *file, QSP_BOOL isNewGame)
  348. //{
  349. // if (m_frame->IsQuit()) return;
  350. // if (QSPLoadGameWorld(file, isNewGame) && isNewGame)
  351. // {
  352. // QFileInfo fileName(QSPTools::qspStrToQt(file));
  353. // m_gamePath = fileName.canonicalPath();
  354. // if(!m_gamePath.endsWith('/')) m_gamePath+="/";
  355. // m_frame->UpdateGamePath(m_gamePath);
  356. // }
  357. //}
  358. void QSPCallBacks::OpenGameStatus(const QSP_CHAR *file)
  359. {
  360. if (m_frame->IsQuit()) return;
  361. if (file)
  362. {
  363. QFileInfo fileInfo(QSPTools::qspStrToQt(file));
  364. if ( fileInfo.exists() && fileInfo.isFile() ) QSPOpenSavedGame(file, QSP_FALSE);
  365. }
  366. else
  367. {
  368. m_frame->EnableControls(false);
  369. QString path = QFileDialog::getOpenFileName(m_frame, MainWindow::tr("Select saved game file"), m_frame->GetLastPath(), MainWindow::tr("Saved game files (*.sav)"));
  370. m_frame->EnableControls(true);
  371. if (!path.isEmpty())
  372. {
  373. m_frame->SetLastPath(QFileInfo(path).canonicalPath());
  374. QSPOpenSavedGame(qspStringFromQString(path), QSP_FALSE);
  375. }
  376. }
  377. }
  378. void QSPCallBacks::SaveGameStatus(const QSP_CHAR *file)
  379. {
  380. if (m_frame->IsQuit()) return;
  381. if (file)
  382. QSPSaveGame(file, QSP_FALSE);
  383. else
  384. {
  385. m_frame->EnableControls(false);
  386. QString path = QFileDialog::getSaveFileName(m_frame, MainWindow::tr("Select file to save"), m_frame->GetLastPath(), MainWindow::tr("Saved game files (*.sav)"));
  387. m_frame->EnableControls(true);
  388. if (!path.isEmpty())
  389. {
  390. m_frame->SetLastPath(QFileInfo(path).canonicalPath());
  391. QSPSaveGame(qspStringFromQString(path), QSP_FALSE);
  392. }
  393. }
  394. }
  395. void QSPCallBacks::UpdateGamePath()
  396. {
  397. QFileInfo fileName(QSPTools::qspStrToQt(QSPGetQstFullPath()));
  398. m_gamePath = fileName.canonicalPath();
  399. if(!m_gamePath.endsWith("/")) m_gamePath+="/";
  400. //m_frame->UpdateGamePath(m_gamePath);
  401. m_frame->GetDesc()->SetGamePath(m_gamePath);
  402. m_frame->GetObjects()->SetGamePath(m_gamePath);
  403. m_frame->GetActions()->SetGamePath(m_gamePath);
  404. m_frame->GetVars()->SetGamePath(m_gamePath);
  405. m_frame->GetImgView()->SetGamePath(m_gamePath);
  406. }
  407. bool QSPCallBacks::SetVolume(const QSP_CHAR *file, int volume)
  408. {
  409. if (!IsPlay(file)) return false;
  410. QSPSounds::iterator elem = m_sounds.find(QString(QFileInfo(m_gamePath + QSPTools::GetCaseInsensitiveFilePath(m_gamePath, QSPTools::qspStrToQt(file))).absoluteFilePath()));
  411. QMediaPlayer *snd = elem.value();
  412. snd->setVolume(volume*m_volumeCoeff);
  413. return true;
  414. }
  415. void QSPCallBacks::SetOverallVolume(float coeff)
  416. {
  417. QMediaPlayer *snd;
  418. if (coeff < 0.0)
  419. coeff = 0.0;
  420. else if (coeff > 1.0)
  421. coeff = 1.0;
  422. m_volumeCoeff = coeff;
  423. for (QSPSounds::iterator i = m_sounds.begin(); i != m_sounds.end(); ++i)
  424. {
  425. snd = i.value();
  426. if (snd->state() == QMediaPlayer::PlayingState)
  427. snd->setVolume(snd->volume()*m_volumeCoeff);
  428. }
  429. }
  430. void QSPCallBacks::SetAllowHTML5Extras(bool HTML5Extras)
  431. {
  432. m_isAllowHTML5Extras = HTML5Extras;
  433. }
  434. void QSPCallBacks::UpdateSounds()
  435. {
  436. QMediaPlayer *snd;
  437. QSPSounds::iterator i = m_sounds.begin();
  438. while (i != m_sounds.end())
  439. {
  440. snd = i.value();
  441. if(snd->state() == QMediaPlayer::PlayingState)
  442. ++i;
  443. else
  444. {
  445. delete snd;
  446. i = m_sounds.erase(i);
  447. }
  448. }
  449. }