PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/milkytracker-0.90.85/src/tracker/DialogQuickChooseInstrument.cpp

#
C++ | 369 lines | 275 code | 63 blank | 31 comment | 36 complexity | 593e2dac30605477c31720dda62940a3 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * tracker/DialogQuickChooseInstrument.cpp
  3. *
  4. * Copyright 2009 Peter Barth
  5. *
  6. * This file is part of Milkytracker.
  7. *
  8. * Milkytracker is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * Milkytracker is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with Milkytracker. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /*
  23. * DialogWithValues.cpp
  24. * MilkyTracker
  25. *
  26. * Created by Peter Barth on 25.10.05.
  27. *
  28. */
  29. #include "DialogQuickChooseInstrument.h"
  30. #include "Screen.h"
  31. #include "StaticText.h"
  32. #include "MessageBoxContainer.h"
  33. #include "Font.h"
  34. #include "ListBox.h"
  35. #include "Seperator.h"
  36. DialogQuickChooseInstrument::DialogQuickChooseInstrument(PPScreen* screen,
  37. DialogResponder* responder,
  38. pp_int32 id,
  39. const PPString& caption) :
  40. PPDialogBase()
  41. {
  42. value = 0;
  43. valueRangeStart = 0;
  44. valueRangeEnd = 0xFF;
  45. valueIncreaseStep = 1;
  46. #ifdef __LOWRES__
  47. initDialog(screen, responder, id, caption, 290, 110+15, 26+15, "Ok", "Cancel");
  48. #else
  49. initDialog(screen, responder, id, caption, 290, 110, 26, "Ok", "Cancel");
  50. #endif
  51. pp_int32 x = getMessageBoxContainer()->getLocation().x;
  52. pp_int32 width = getMessageBoxContainer()->getSize().width;
  53. pp_int32 x2 = x;
  54. pp_int32 y2 = getMessageBoxContainer()->getControlByID(MESSAGEBOX_STATICTEXT_MAIN_CAPTION)->getLocation().y;
  55. PPButton* button;
  56. //setValueOneCaption("Enter new volume in percent");
  57. y2 +=20+12;
  58. // enter edit field 1
  59. x2 = x + width / 2 - (100+35)/2;
  60. PPListBox* listBox = new PPListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, screen, this, PPPoint(x2, y2), PPSize(100,12), true, true, false);
  61. listBox->showSelection(false);
  62. listBox->setBorderColor(messageBoxContainerGeneric->getColor());
  63. listBox->setMaxEditSize(8);
  64. messageBoxContainerGeneric->addControl(listBox);
  65. button = new PPButton(MESSAGEBOX_BUTTON_INCREASE_VALUEONE, screen, this, PPPoint(x2 + listBox->getSize().width + 2, y2), PPSize(16, 11));
  66. button->setText("+");
  67. messageBoxContainerGeneric->addControl(button);
  68. button = new PPButton(MESSAGEBOX_BUTTON_DECREASE_VALUEONE, screen, this, PPPoint(x2 + listBox->getSize().width + 2 + button->getSize().width + 1, y2), PPSize(16, 11));
  69. button->setText("-");
  70. messageBoxContainerGeneric->addControl(button);
  71. #ifdef __LOWRES__
  72. pp_int32 height = getMessageBoxContainer()->getSize().height;
  73. pp_int32 y = getMessageBoxContainer()->getLocation().y;
  74. const char buttonTexts[] = {'1','2','3','4','5','6','7','8','9','0','+','-','.','<','>'};
  75. pp_int32 bWidth = (width - 22*2 - 2*3) / sizeof(buttonTexts);
  76. pp_int32 x2_2 = x+4;
  77. pp_int32 y2_2 = y+height - 4 - 13;
  78. messageBoxContainerGeneric->addControl(new PPSeperator(0, screen, PPPoint(x2_2-1, y2_2-3), width-2*3, messageBoxContainerGeneric->getColor(), true));
  79. pp_uint32 i = 0;
  80. for (i = 0; i < sizeof(buttonTexts); i++)
  81. {
  82. button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1, 13));
  83. button->setText(buttonTexts[i]);
  84. messageBoxContainerGeneric->addControl(button);
  85. x2_2+=bWidth;
  86. }
  87. bWidth = 22;
  88. button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1-3, 13));
  89. button->setFont(PPFont::getFont(PPFont::FONT_TINY));
  90. button->setText("Del");
  91. messageBoxContainerGeneric->addControl(button);
  92. x2_2+=bWidth-3;
  93. i++;
  94. button = new PPButton(MESSAGEBOX_BUTTON_KEYS_BASE+i, screen, this, PPPoint(x2_2, y2_2), PPSize(bWidth+1, 13));
  95. button->setFont(PPFont::getFont(PPFont::FONT_TINY));
  96. button->setText("Back");
  97. messageBoxContainerGeneric->addControl(button);
  98. #endif
  99. fitListBoxes();
  100. updateListBoxes();
  101. }
  102. void DialogQuickChooseInstrument::setValueCaption(const PPString& caption)
  103. {
  104. PPControl* ctrl = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_VALUE_ONE_CAPTION);
  105. if (ctrl)
  106. messageBoxContainerGeneric->removeControl(ctrl);
  107. pp_int32 width = messageBoxContainerGeneric->getSize().width;
  108. pp_int32 x = messageBoxContainerGeneric->getLocation().x;
  109. pp_int32 y = messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_MAIN_CAPTION)->getLocation().y;
  110. y+=20;
  111. x += width / 2 - (PPFont::getFont(PPFont::FONT_SYSTEM)->getStrWidth(caption) / 2);
  112. messageBoxContainerGeneric->addControl(new PPStaticText(MESSAGEBOX_STATICTEXT_VALUE_ONE_CAPTION, parentScreen, this, PPPoint(x, y), caption, true));
  113. }
  114. void DialogQuickChooseInstrument::show(bool b/* = true*/)
  115. {
  116. if (b)
  117. listBoxEnterEditState(MESSAGEBOX_LISTBOX_VALUE_ONE);
  118. PPDialogBase::show(b);
  119. }
  120. pp_uint16 DialogQuickChooseInstrument::numPadKeyToValue(pp_uint16 keyCode)
  121. {
  122. switch (keyCode)
  123. {
  124. case VK_NUMPAD0:
  125. return 0;
  126. case VK_NUMPAD1:
  127. return 1;
  128. case VK_NUMPAD2:
  129. return 2;
  130. case VK_NUMPAD3:
  131. return 3;
  132. case VK_NUMPAD4:
  133. return 4;
  134. case VK_NUMPAD5:
  135. return 5;
  136. case VK_NUMPAD6:
  137. return 6;
  138. case VK_NUMPAD7:
  139. return 7;
  140. case VK_NUMPAD8:
  141. return 8;
  142. case VK_NUMPAD9:
  143. return 9;
  144. case VK_DIVIDE:
  145. return 0x0A;
  146. case VK_MULTIPLY:
  147. return 0x0B;
  148. case VK_SUBTRACT:
  149. return 0x0C;
  150. case VK_ADD:
  151. return 0x0D;
  152. case VK_SEPARATOR:
  153. return 0x0E;
  154. case VK_DECIMAL:
  155. return 0x0F;
  156. default:
  157. return 0xFFFF;
  158. }
  159. }
  160. static pp_uint8 getNibble(const char* str)
  161. {
  162. if (*str >= '0' && *str <= '9')
  163. return (*str - '0');
  164. if (*str >= 'A' && *str <= 'F')
  165. return (*str - 'A' + 10);
  166. if (*str >= 'a' && *str <= 'f')
  167. return (*str - 'a' + 10);
  168. return 0;
  169. }
  170. static pp_uint8 getByte(const char* str)
  171. {
  172. return (getNibble(str)<<4) + getNibble(str+1);
  173. }
  174. pp_int32 DialogQuickChooseInstrument::handleEvent(PPObject* sender, PPEvent* event)
  175. {
  176. if (event->getID() == eKeyChar)
  177. {
  178. event->cancel();
  179. }
  180. else if (event->getID() == eKeyDown)
  181. {
  182. PPDialogBase::handleEvent(sender, event);
  183. if (event->getID() == eInvalid)
  184. return 0;
  185. pp_uint16 keyCode = *((pp_uint16*)event->getDataPtr());
  186. pp_uint16 chr = numPadKeyToValue(keyCode);
  187. if (chr <= 0xF)
  188. {
  189. PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
  190. const char* transTab = "0123456789abcdef";
  191. chr = transTab[chr];
  192. listBox->dispatchEvent(event);
  193. PPEvent event2(eKeyChar, &chr, sizeof(chr));
  194. listBox->dispatchEvent(&event2);
  195. if (listBox->getItem(0).length() == 2)
  196. {
  197. commitChanges();
  198. PPButton* button = static_cast<PPButton*>(messageBoxContainerGeneric->getControlByID(PP_MESSAGEBOX_BUTTON_YES));
  199. if (button)
  200. {
  201. PPEvent event(eCommand);
  202. PPDialogBase::handleEvent(reinterpret_cast<PPObject*>(button), &event);
  203. }
  204. }
  205. return 0;
  206. }
  207. }
  208. else if (event->getID() == eCommand || event->getID() == eCommandRepeat)
  209. {
  210. switch (reinterpret_cast<PPControl*>(sender)->getID())
  211. {
  212. case PP_MESSAGEBOX_BUTTON_YES:
  213. {
  214. commitChanges();
  215. break;
  216. }
  217. case MESSAGEBOX_BUTTON_INCREASE_VALUEONE:
  218. {
  219. setValue(value+valueIncreaseStep);
  220. parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
  221. break;
  222. }
  223. case MESSAGEBOX_BUTTON_DECREASE_VALUEONE:
  224. {
  225. setValue(value-valueIncreaseStep);
  226. parentScreen->paintControl(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
  227. break;
  228. }
  229. }
  230. }
  231. else if (event->getID() == eValueChanged)
  232. {
  233. switch (reinterpret_cast<PPControl*>(sender)->getID())
  234. {
  235. // song title
  236. case MESSAGEBOX_LISTBOX_VALUE_ONE:
  237. {
  238. const PPString* str = *(reinterpret_cast<const PPString* const*>(event->getDataPtr()));
  239. setValue(getByte(*str));
  240. break;
  241. }
  242. }
  243. }
  244. return PPDialogBase::handleEvent(sender, event);
  245. }
  246. void DialogQuickChooseInstrument::fitListBoxes()
  247. {
  248. fitListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, valueRangeStart, valueRangeEnd);
  249. }
  250. void DialogQuickChooseInstrument::fitListBox(pp_int32 id, pp_int32 valueOneRangeStart, pp_int32 valueOneRangeEnd)
  251. {
  252. pp_int32 width = messageBoxContainerGeneric->getSize().width;
  253. pp_int32 x = messageBoxContainerGeneric->getLocation().x;
  254. char buffer1[100];
  255. char buffer2[100];
  256. sprintf(buffer1, "%%x");
  257. PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
  258. if (listBox)
  259. {
  260. sprintf(buffer2, buffer1, valueRangeStart);
  261. pp_int32 len = (pp_int32)strlen(buffer2)+1;
  262. sprintf(buffer2, buffer1, valueRangeEnd);
  263. if ((pp_int32)strlen(buffer2)+1 > len) len = (pp_int32)strlen(buffer2)+1;
  264. pp_int32 y2 = listBox->getLocation().y;
  265. pp_int32 x2 = x + width / 2 - ((len*8)+10+35)/2;
  266. listBox->setLocation(PPPoint(x2, y2));
  267. listBox->setSize(PPSize(len*8+10, listBox->getSize().height));
  268. x2+=listBox->getSize().width + 2;
  269. PPButton* button = static_cast<PPButton*>(messageBoxContainerGeneric->getControlByID(id+1));
  270. y2 = button->getLocation().y;
  271. button->setLocation(PPPoint(x2, y2));
  272. x2+=button->getSize().width+1;
  273. button = static_cast<PPButton*>(messageBoxContainerGeneric->getControlByID(id+2));
  274. y2 = button->getLocation().y;
  275. button->setLocation(PPPoint(x2, y2));
  276. }
  277. }
  278. void DialogQuickChooseInstrument::updateListBoxes()
  279. {
  280. updateListBox(MESSAGEBOX_LISTBOX_VALUE_ONE, value);
  281. }
  282. void DialogQuickChooseInstrument::updateListBox(pp_int32 id, pp_int32 val)
  283. {
  284. char buffer1[100];
  285. char buffer2[100];
  286. sprintf(buffer1, "%%x");
  287. PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
  288. if (listBox)
  289. {
  290. sprintf(buffer2, buffer1, val);
  291. listBox->clear();
  292. listBox->addItem(buffer2);
  293. }
  294. }
  295. void DialogQuickChooseInstrument::commitChanges()
  296. {
  297. PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_LISTBOX_VALUE_ONE));
  298. if (listBox)
  299. listBox->commitChanges();
  300. }
  301. void DialogQuickChooseInstrument::listBoxEnterEditState(pp_int32 id)
  302. {
  303. PPListBox* listBox = static_cast<PPListBox*>(messageBoxContainerGeneric->getControlByID(id));
  304. if (listBox)
  305. listBox->placeCursorAtEnd();
  306. }