callbacks_gui.cpp 15 KB

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