mselect.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. /*
  2. About: Model Select with previews.
  3. Author: ziggi
  4. TextDraw's based on vspawner script by Kye
  5. */
  6. #if !defined _samp_included
  7. #error "Please include a_samp or a_npc before mselect"
  8. #endif
  9. #if defined _mselect_included
  10. #endinput
  11. #endif
  12. #define _mselect_included
  13. /*
  14. Define const
  15. */
  16. #if !defined MSELECT_MAX_ITEMS
  17. #define MSELECT_MAX_ITEMS 100
  18. #endif
  19. #if !defined MSELECT_MAX_ITEMS_PER_LINE
  20. #define MSELECT_MAX_ITEMS_PER_LINE 7
  21. #endif
  22. #if !defined MSELECT_MAX_ITEMS_LINES
  23. #define MSELECT_MAX_ITEMS_LINES 3
  24. #endif
  25. #if !defined MSELECT_DEF_LIST_LOOP
  26. #define MSELECT_DEF_LIST_LOOP false
  27. #endif
  28. #if !defined MSELECT_DEF_BUTTON_TEXT
  29. #define MSELECT_DEF_BUTTON_TEXT "Cancel"
  30. #endif
  31. #if !defined MSELECT_DEF_BUTTON_NEXT
  32. #define MSELECT_DEF_BUTTON_NEXT ">>"
  33. #endif
  34. #if !defined MSELECT_DEF_BUTTON_PREV
  35. #define MSELECT_DEF_BUTTON_PREV "<<"
  36. #endif
  37. #if !defined MSELECT_DEF_POS_X
  38. #define MSELECT_DEF_POS_X 85.0
  39. #endif
  40. #if !defined MSELECT_DEF_POS_Y
  41. #define MSELECT_DEF_POS_Y 130.0
  42. #endif
  43. #if !defined MSELECT_DEF_BUTTON_WIDTH
  44. #define MSELECT_DEF_BUTTON_WIDTH 60.0
  45. #endif
  46. #if !defined MSELECT_DEF_BUTTON_HEIGHT
  47. #define MSELECT_DEF_BUTTON_HEIGHT 13.0
  48. #endif
  49. #if !defined MSELECT_DEF_PBUTTON_WIDTH
  50. #define MSELECT_DEF_PBUTTON_WIDTH 30.0
  51. #endif
  52. #if !defined MSELECT_DEF_PBUTTON_HEIGHT
  53. #define MSELECT_DEF_PBUTTON_HEIGHT 13.0
  54. #endif
  55. #if !defined MSELECT_DEF_ITEM_WIDTH
  56. #define MSELECT_DEF_ITEM_WIDTH 60.0
  57. #endif
  58. #if !defined MSELECT_DEF_ITEM_HEIGHT
  59. #define MSELECT_DEF_ITEM_HEIGHT 70.0
  60. #endif
  61. #if !defined MSELECT_DEF_ROT_X
  62. #define MSELECT_DEF_ROT_X 0.0
  63. #endif
  64. #if !defined MSELECT_DEF_ROT_Y
  65. #define MSELECT_DEF_ROT_Y 0.0
  66. #endif
  67. #if !defined MSELECT_DEF_ROT_Z
  68. #define MSELECT_DEF_ROT_Z 0.0
  69. #endif
  70. #if !defined MSELECT_DEF_ZOOM
  71. #define MSELECT_DEF_ZOOM 1.0
  72. #endif
  73. #if !defined MSELECT_DEF_BG_PADDING
  74. #define MSELECT_DEF_BG_PADDING 20.0
  75. #endif
  76. #if !defined MSELECT_DEF_ITEM_PADDING
  77. #define MSELECT_DEF_ITEM_PADDING 2.0
  78. #endif
  79. #if !defined MSELECT_DEF_BUTTON_PADDING
  80. #define MSELECT_DEF_BUTTON_PADDING 5.0
  81. #endif
  82. #if !defined MSELECT_DEF_SELECT_COLOR
  83. #define MSELECT_DEF_SELECT_COLOR 0xAAAAAAFF
  84. #endif
  85. #if !defined MSELECT_DEF_ITEMS_BG_COLOR
  86. #define MSELECT_DEF_ITEMS_BG_COLOR 0x55555599
  87. #endif
  88. #if !defined MSELECT_DEF_DIALOG_BG_COLOR
  89. #define MSELECT_DEF_DIALOG_BG_COLOR 0x00000099
  90. #endif
  91. #if !defined MSELECT_DEF_HEADER_FG_COLOR
  92. #define MSELECT_DEF_HEADER_FG_COLOR 0xDDDDDDDD
  93. #endif
  94. #if !defined MSELECT_DEF_PAGE_FG_COLOR
  95. #define MSELECT_DEF_PAGE_FG_COLOR 0xDDDDDDDD
  96. #endif
  97. #if !defined MSELECT_DEF_BUTTON_FG_COLOR
  98. #define MSELECT_DEF_BUTTON_FG_COLOR 0x888888FF
  99. #endif
  100. #if !defined MSELECT_DEF_BUTTON_BG_COLOR
  101. #define MSELECT_DEF_BUTTON_BG_COLOR 0x000000CC
  102. #endif
  103. #if !defined MSELECT_DEF_HEADER_PADDING
  104. #define MSELECT_DEF_HEADER_PADDING 3.0
  105. #endif
  106. #if !defined MSELECT_DEF_PAGE_PADDING
  107. #define MSELECT_DEF_PAGE_PADDING 3.0
  108. #endif
  109. #define MSELECT_MAX_ITEMS_ON_LIST (MSELECT_MAX_ITEMS_PER_LINE * MSELECT_MAX_ITEMS_LINES)
  110. #define MSELECT_MAX_FUNCTION_NAME 31
  111. #define MSELECT_INVALID_MODEL_ID -1
  112. /*
  113. Define functions
  114. */
  115. #define MSelectCreate:%0(%1) \
  116. forward msc_%0(%1); \
  117. public msc_%0(%1)
  118. #define MSelectResponse:%0(%1) \
  119. forward msr_%0(%1); \
  120. public msr_%0(%1)
  121. #define MSelect: #
  122. /*
  123. Enums
  124. */
  125. enum MSelectType {
  126. MSelect_None,
  127. MSelect_Item,
  128. MSelect_Button,
  129. MSelect_ButtonNext,
  130. MSelect_ButtonPrev,
  131. MSelect_Cancel,
  132. }
  133. /*
  134. Vars
  135. */
  136. static
  137. bool:IsOpen[MAX_PLAYERS],
  138. ItemsCount[MAX_PLAYERS],
  139. ListItemID[MAX_PLAYERS],
  140. ListItemModel[MAX_PLAYERS],
  141. ListItemPage[MAX_PLAYERS],
  142. ListPage[MAX_PLAYERS],
  143. bool:ListLoop[MAX_PLAYERS],
  144. FunctionName[MAX_PLAYERS][MSELECT_MAX_FUNCTION_NAME],
  145. bool:TD_SkipCancel[MAX_PLAYERS],
  146. TD_ItemsModel[MAX_PLAYERS][MSELECT_MAX_ITEMS],
  147. TD_ItemsBgColors[MAX_PLAYERS][MSELECT_MAX_ITEMS],
  148. TD_PageFgColor[MAX_PLAYERS],
  149. TD_SelectColor[MAX_PLAYERS],
  150. Float:TD_PosX[MAX_PLAYERS],
  151. Float:TD_PosY[MAX_PLAYERS],
  152. Float:TD_ItemWidth[MAX_PLAYERS],
  153. Float:TD_ItemHeight[MAX_PLAYERS],
  154. Float:TD_RotX[MAX_PLAYERS],
  155. Float:TD_RotY[MAX_PLAYERS],
  156. Float:TD_RotZ[MAX_PLAYERS],
  157. Float:TD_Zoom[MAX_PLAYERS],
  158. Float:TD_PaddingBackground[MAX_PLAYERS],
  159. Float:TD_PaddingButton[MAX_PLAYERS],
  160. Float:TD_PaddingItem[MAX_PLAYERS],
  161. Float:TD_PaddingPage[MAX_PLAYERS],
  162. PlayerText:TD_Header[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...},
  163. PlayerText:TD_Item[MAX_PLAYERS][MSELECT_MAX_ITEMS],
  164. PlayerText:TD_ButtonCancel[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...},
  165. PlayerText:TD_ButtonNext[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...},
  166. PlayerText:TD_ButtonPrev[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...},
  167. PlayerText:TD_Page[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...},
  168. PlayerText:TD_Background[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
  169. /*
  170. Public functions
  171. */
  172. stock MSelect_Show(playerid, function[])
  173. {
  174. new call_func[MSELECT_MAX_FUNCTION_NAME] = "msc_";
  175. strcat(call_func, function);
  176. CallLocalFunction(call_func, "i", playerid);
  177. }
  178. stock MSelect_Close(playerid)
  179. {
  180. IsOpen[playerid] = false;
  181. TD_Remove(playerid, TD_Header[playerid]);
  182. TD_Remove(playerid, TD_Page[playerid]);
  183. TD_Remove(playerid, TD_Background[playerid]);
  184. TD_Remove(playerid, TD_ButtonNext[playerid]);
  185. TD_Remove(playerid, TD_ButtonPrev[playerid]);
  186. TD_Remove(playerid, TD_ButtonCancel[playerid]);
  187. for (new i = 0; i < sizeof(TD_ItemsModel[]); i++) {
  188. TD_ItemsModel[playerid][i] = MSELECT_INVALID_MODEL_ID;
  189. TD_Remove(playerid, TD_Item[playerid][i]);
  190. }
  191. TD_SkipCancel[playerid] = true;
  192. CancelSelectTextDraw(playerid);
  193. }
  194. stock MSelect_Open(playerid, function[], items_array[], items_count, bool:list_loop = MSELECT_DEF_LIST_LOOP,
  195. header[] = "", button[] = MSELECT_DEF_BUTTON_TEXT,
  196. button_next[] = MSELECT_DEF_BUTTON_NEXT, button_prev[] = MSELECT_DEF_BUTTON_PREV,
  197. Float:pos_x = MSELECT_DEF_POS_X, Float:pos_y = MSELECT_DEF_POS_Y,
  198. Float:button_width = MSELECT_DEF_BUTTON_WIDTH, Float:button_height = MSELECT_DEF_BUTTON_HEIGHT,
  199. Float:page_button_width = MSELECT_DEF_PBUTTON_WIDTH, Float:page_button_height = MSELECT_DEF_PBUTTON_HEIGHT,
  200. Float:item_width = MSELECT_DEF_ITEM_WIDTH, Float:item_height = MSELECT_DEF_ITEM_HEIGHT,
  201. Float:rot_x = MSELECT_DEF_ROT_X, Float:rot_y = MSELECT_DEF_ROT_Y, Float:rot_z = MSELECT_DEF_ROT_Z,
  202. Float:zoom = MSELECT_DEF_ZOOM, Float:background_padding = MSELECT_DEF_BG_PADDING,
  203. Float:item_padding = MSELECT_DEF_ITEM_PADDING, Float:button_padding = MSELECT_DEF_BUTTON_PADDING,
  204. Float:header_padding = MSELECT_DEF_HEADER_PADDING, Float:page_padding = MSELECT_DEF_PAGE_PADDING,
  205. select_color = MSELECT_DEF_SELECT_COLOR,
  206. items_bg_colors[MSELECT_MAX_ITEMS] = {MSELECT_DEF_ITEMS_BG_COLOR, ...},
  207. dialog_bg_color = MSELECT_DEF_DIALOG_BG_COLOR,
  208. header_fg_color = MSELECT_DEF_HEADER_FG_COLOR,
  209. page_fg_color = MSELECT_DEF_PAGE_FG_COLOR,
  210. button_fg_color = MSELECT_DEF_BUTTON_FG_COLOR,
  211. button_bg_color = MSELECT_DEF_BUTTON_BG_COLOR)
  212. {
  213. MSelect_Close(playerid);
  214. if (items_count > MSELECT_MAX_ITEMS) {
  215. printf("Error (MSelect): list count value is too big (%d, max is %d).", items_count, MSELECT_MAX_ITEMS);
  216. items_count = MSELECT_MAX_ITEMS;
  217. }
  218. IsOpen[playerid] = true;
  219. ItemsCount[playerid] = items_count;
  220. ListItemID[playerid] = -1;
  221. ListItemModel[playerid] = MSELECT_INVALID_MODEL_ID;
  222. ListItemPage[playerid] = 0;
  223. ListPage[playerid] = 0;
  224. ListLoop[playerid] = list_loop;
  225. TD_PosX[playerid] = pos_x;
  226. TD_PosY[playerid] = pos_y;
  227. TD_ItemWidth[playerid] = item_width;
  228. TD_ItemHeight[playerid] = item_height;
  229. TD_RotX[playerid] = rot_x;
  230. TD_RotY[playerid] = rot_y;
  231. TD_RotZ[playerid] = rot_z;
  232. TD_Zoom[playerid] = zoom;
  233. TD_PaddingBackground[playerid] = background_padding;
  234. TD_PaddingButton[playerid] = button_padding;
  235. TD_PaddingItem[playerid] = item_padding;
  236. TD_PaddingPage[playerid] = page_padding;
  237. TD_ItemsBgColors[playerid] = items_bg_colors;
  238. TD_PageFgColor[playerid] = page_fg_color;
  239. TD_SelectColor[playerid] = select_color;
  240. MS_strcpy(FunctionName[playerid], function, MSELECT_MAX_FUNCTION_NAME);
  241. for (new i = 0; i < items_count; i++) {
  242. TD_ItemsModel[playerid][i] = items_array[i];
  243. }
  244. // background
  245. TD_BackgroundCreate(playerid, dialog_bg_color, TD_PosX[playerid], TD_PosY[playerid],
  246. TD_ItemWidth[playerid], TD_ItemHeight[playerid],
  247. TD_PaddingBackground[playerid], TD_PaddingButton[playerid]);
  248. // buttons
  249. new Float:button_x = pos_x + background_padding + MSELECT_MAX_ITEMS_PER_LINE * (TD_ItemWidth[playerid] + item_padding) - 5.0;
  250. new Float:button_y = pos_y + background_padding * 1.5 + MSELECT_MAX_ITEMS_LINES * (TD_ItemHeight[playerid] + item_padding) + 5.0;
  251. TD_ButtonCreate(playerid, TD_ButtonNext[playerid],
  252. button_next, button_bg_color, button_fg_color,
  253. button_x - page_button_width / 2.0, button_y, page_button_width, page_button_height);
  254. TD_ButtonCreate(playerid, TD_ButtonPrev[playerid],
  255. button_prev, button_bg_color, button_fg_color,
  256. button_x - page_button_width * 1.5 - button_padding, button_y, page_button_width, page_button_height);
  257. TD_ButtonCreate(playerid, TD_ButtonCancel[playerid],
  258. button, button_bg_color, button_fg_color,
  259. button_x - page_button_width * 2.0 - button_width / 2.0 - button_padding * 2.0, button_y, button_width, button_height);
  260. // header
  261. if (strlen(header) != 0) {
  262. TD_HeaderCreate(playerid, header, header_fg_color, TD_PosX[playerid] + header_padding, TD_PosY[playerid]);
  263. }
  264. // page
  265. TD_SetPage(playerid, ListPage[playerid], TD_ItemsModel[playerid], ItemsCount[playerid],
  266. ListLoop[playerid], TD_PosX[playerid], TD_PosY[playerid],
  267. TD_RotX[playerid], TD_RotY[playerid], TD_RotZ[playerid], TD_Zoom[playerid],
  268. TD_ItemWidth[playerid], TD_ItemHeight[playerid],
  269. TD_PaddingBackground[playerid], TD_PaddingItem[playerid], TD_PaddingPage[playerid],
  270. TD_ItemsBgColors[playerid], TD_PageFgColor[playerid]);
  271. SelectTextDraw(playerid, select_color);
  272. }
  273. stock MSelect_IsOpen(playerid)
  274. {
  275. return _:IsOpen[playerid];
  276. }
  277. /*
  278. Private functions
  279. */
  280. static stock TD_SetPage(playerid, &page_id, items_array[], items_count, bool:list_loop,
  281. Float:pos_x, Float:pos_y, Float:rot_x, Float:rot_y, Float:rot_z, Float:zoom,
  282. Float:width, Float:height, Float:padding_bg, Float:padding_item, Float:padding_page,
  283. items_bg_colors[MSELECT_MAX_ITEMS], page_fg_color)
  284. {
  285. // list
  286. new pages_count, start_index, end_index;
  287. GetPaginatorInfo(items_count, page_id, pages_count, start_index, end_index, list_loop);
  288. new
  289. bool:IsDefaultItemCount = end_index - start_index == MSELECT_MAX_ITEMS_ON_LIST,
  290. bool:IsListCreated = TD_Item[playerid][0] != PlayerText:INVALID_TEXT_DRAW,
  291. bool:IsPageChanged = page_id != ListPage[playerid];
  292. if (IsDefaultItemCount && IsListCreated && IsPageChanged) {
  293. // update list
  294. new current_row = 0;
  295. for (new i = start_index; i < end_index; i++) {
  296. current_row++;
  297. TD_ListUpdateModel(playerid, current_row, items_array[i]);
  298. }
  299. // update paginator
  300. if (pages_count > 1) {
  301. new string[16];
  302. format(string, sizeof(string), "%d/%d", page_id + 1, pages_count);
  303. TD_PaginatorUpdateText(playerid, string);
  304. }
  305. } else {
  306. // remove old page
  307. TD_Remove(playerid, TD_Page[playerid]);
  308. for (new i = 0; i < MSELECT_MAX_ITEMS; i++) {
  309. TD_Remove(playerid, TD_Item[playerid][i]);
  310. }
  311. // draw list
  312. new
  313. row,
  314. Float:x,
  315. Float:y;
  316. for (new i = start_index; i < end_index; i++) {
  317. x = pos_x + padding_bg + (row % MSELECT_MAX_ITEMS_PER_LINE) * (width + padding_item);
  318. y = pos_y + padding_bg + (row / MSELECT_MAX_ITEMS_PER_LINE) * (height + padding_item);
  319. row++;
  320. TD_ItemCreate(playerid, i, items_array[i], items_bg_colors[i],
  321. x, y, rot_x, rot_y, rot_z, zoom, width, height);
  322. }
  323. // paginator
  324. if (pages_count > 1) {
  325. new string[16];
  326. format(string, sizeof(string), "%d/%d", page_id + 1, pages_count);
  327. TD_PaginatorCreate(playerid, string, page_fg_color,
  328. pos_x - padding_page + padding_bg * 2.0 + MSELECT_MAX_ITEMS_PER_LINE * (width + padding_item),
  329. pos_y);
  330. }
  331. }
  332. if (page_id == ListItemPage[playerid]) {
  333. TD_SelectItem(playerid, ListItemID[playerid]);
  334. }
  335. }
  336. static stock GetPaginatorInfo(items_count, &curr_page = 0, &max_page = 0, &start_index = 0, &end_index = 0, bool:list_loop = false)
  337. {
  338. if (items_count <= 0) {
  339. return;
  340. }
  341. max_page = items_count / MSELECT_MAX_ITEMS_ON_LIST;
  342. if (items_count % MSELECT_MAX_ITEMS_ON_LIST != 0) {
  343. max_page++;
  344. }
  345. if (curr_page < 0) {
  346. if (list_loop) {
  347. curr_page = max_page - 1;
  348. } else {
  349. curr_page = 0;
  350. }
  351. } else if (curr_page > max_page - 1) {
  352. if (list_loop) {
  353. curr_page = 0;
  354. } else {
  355. curr_page = max_page - 1;
  356. }
  357. }
  358. start_index = curr_page * MSELECT_MAX_ITEMS_ON_LIST;
  359. end_index = start_index + MSELECT_MAX_ITEMS_ON_LIST;
  360. if (items_count % end_index == items_count) {
  361. end_index = start_index + items_count % MSELECT_MAX_ITEMS_ON_LIST;
  362. }
  363. }
  364. static stock TD_SelectItem(playerid, item_id)
  365. {
  366. if (!(0 <= item_id < ItemsCount[playerid])) {
  367. return 0;
  368. }
  369. new prev_item_id = ListItemID[playerid];
  370. if (prev_item_id != -1) {
  371. PlayerTextDrawBackgroundColor(playerid, TD_Item[playerid][prev_item_id], TD_ItemsBgColors[playerid][prev_item_id]);
  372. PlayerTextDrawShow(playerid, TD_Item[playerid][prev_item_id]);
  373. }
  374. PlayerTextDrawBackgroundColor(playerid, TD_Item[playerid][item_id], TD_SelectColor[playerid]);
  375. PlayerTextDrawShow(playerid, TD_Item[playerid][item_id]);
  376. ListItemID[playerid] = item_id;
  377. ListItemModel[playerid] = TD_ItemsModel[playerid][item_id];
  378. ListItemPage[playerid] = ListPage[playerid];
  379. return 1;
  380. }
  381. static stock TD_ItemCreate(playerid, item_id, model_id, bg_color, Float:pos_x, Float:pos_y,
  382. Float:rot_x, Float:rot_y, Float:rot_z, Float:zoom,
  383. Float:width, Float:height)
  384. {
  385. TD_Item[playerid][item_id] = CreatePlayerTextDraw(playerid, pos_x, pos_y, " ");
  386. PlayerTextDrawFont(playerid, TD_Item[playerid][item_id], TEXT_DRAW_FONT_MODEL_PREVIEW);
  387. PlayerTextDrawColor(playerid, TD_Item[playerid][item_id], 0xFFFFFFFF);
  388. PlayerTextDrawBackgroundColor(playerid, TD_Item[playerid][item_id], bg_color);
  389. PlayerTextDrawTextSize(playerid, TD_Item[playerid][item_id], width, height);
  390. PlayerTextDrawSetPreviewModel(playerid, TD_Item[playerid][item_id], model_id);
  391. PlayerTextDrawSetPreviewRot(playerid,TD_Item[playerid][item_id], rot_x, rot_y, rot_z, zoom);
  392. PlayerTextDrawSetSelectable(playerid, TD_Item[playerid][item_id], 1);
  393. PlayerTextDrawShow(playerid, TD_Item[playerid][item_id]);
  394. PlayerTextDrawShow(playerid, TD_Item[playerid][item_id]);
  395. }
  396. static stock TD_ListUpdateModel(playerid, item_id, model_id)
  397. {
  398. PlayerTextDrawSetPreviewModel(playerid, TD_Item[playerid][item_id], model_id);
  399. }
  400. static stock TD_PaginatorCreate(playerid, pagestr[], fg_color, Float:pos_x, Float:pos_y)
  401. {
  402. TD_Page[playerid] = CreatePlayerTextDraw(playerid, pos_x, pos_y, pagestr);
  403. PlayerTextDrawUseBox(playerid, TD_Page[playerid], 0);
  404. PlayerTextDrawLetterSize(playerid, TD_Page[playerid], 0.4, 1.1);
  405. PlayerTextDrawFont(playerid, TD_Page[playerid], 1);
  406. PlayerTextDrawSetShadow(playerid, TD_Page[playerid], 0);
  407. PlayerTextDrawSetOutline(playerid, TD_Page[playerid], 1);
  408. PlayerTextDrawColor(playerid, TD_Page[playerid], fg_color);
  409. PlayerTextDrawShow(playerid, TD_Page[playerid]);
  410. PlayerTextDrawAlignment(playerid, TD_Page[playerid], 3);
  411. PlayerTextDrawShow(playerid, TD_Page[playerid]);
  412. }
  413. static stock TD_PaginatorUpdateText(playerid, pagestr[])
  414. {
  415. PlayerTextDrawSetString(playerid, TD_Page[playerid], pagestr);
  416. }
  417. static stock TD_HeaderCreate(playerid, text[], fg_color, Float:pos_x, Float:pos_y)
  418. {
  419. TD_Header[playerid] = CreatePlayerTextDraw(playerid, pos_x, pos_y, text);
  420. PlayerTextDrawUseBox(playerid, TD_Header[playerid], 0);
  421. PlayerTextDrawLetterSize(playerid, TD_Header[playerid], 0.4, 1.4);
  422. PlayerTextDrawFont(playerid, TD_Header[playerid], 1);
  423. PlayerTextDrawSetShadow(playerid, TD_Header[playerid], 0);
  424. PlayerTextDrawSetOutline(playerid, TD_Header[playerid], 1);
  425. PlayerTextDrawColor(playerid, TD_Header[playerid], fg_color);
  426. PlayerTextDrawShow(playerid, TD_Header[playerid]);
  427. PlayerTextDrawShow(playerid, TD_Header[playerid]);
  428. }
  429. static stock TD_BackgroundCreate(playerid, bg_color, Float:pos_x, Float:pos_y, Float:item_width, Float:item_height, Float:padding_bg, Float:padding_item)
  430. {
  431. TD_Background[playerid] = CreatePlayerTextDraw(playerid,
  432. pos_x + padding_bg + (item_width + padding_item) * MSELECT_MAX_ITEMS_PER_LINE,
  433. pos_y, "_");
  434. PlayerTextDrawUseBox(playerid, TD_Background[playerid], 1);
  435. PlayerTextDrawBoxColor(playerid, TD_Background[playerid], bg_color);
  436. PlayerTextDrawLetterSize(playerid, TD_Background[playerid], 0.0,
  437. (item_height * MSELECT_MAX_ITEMS_LINES - padding_bg / 2.0) * 0.135);
  438. PlayerTextDrawTextSize(playerid, TD_Background[playerid], pos_x - 5.0, 0.0);
  439. PlayerTextDrawBackgroundColor(playerid, TD_Background[playerid], bg_color);
  440. PlayerTextDrawShow(playerid, TD_Background[playerid]);
  441. }
  442. static stock TD_ButtonCreate(playerid, &PlayerText:button, text[], bg_color, fg_color,
  443. Float:pos_x, Float:pos_y, Float:width, Float:height)
  444. {
  445. button = CreatePlayerTextDraw(playerid, pos_x, pos_y, text);
  446. PlayerTextDrawUseBox(playerid, button, 1);
  447. PlayerTextDrawBoxColor(playerid, button, bg_color);
  448. PlayerTextDrawBackgroundColor(playerid, button, 0x000000FF);
  449. PlayerTextDrawLetterSize(playerid, button, 0.4, 1.1);
  450. PlayerTextDrawFont(playerid, button, 1);
  451. PlayerTextDrawSetShadow(playerid, button, 0);
  452. PlayerTextDrawSetOutline(playerid, button, 0);
  453. PlayerTextDrawColor(playerid, button, fg_color);
  454. PlayerTextDrawSetSelectable(playerid, button, 1);
  455. PlayerTextDrawAlignment(playerid, button, 2);
  456. PlayerTextDrawTextSize(playerid, button, height, width);
  457. PlayerTextDrawShow(playerid, button);
  458. }
  459. static stock TD_Remove(playerid, &PlayerText:td)
  460. {
  461. PlayerTextDrawHide(playerid, td);
  462. PlayerTextDrawDestroy(playerid, td);
  463. td = PlayerText:INVALID_TEXT_DRAW;
  464. }
  465. /*
  466. OnPlayerDisconnect
  467. */
  468. public OnPlayerDisconnect(playerid, reason)
  469. {
  470. if (MSelect_IsOpen(playerid)) {
  471. MSelect_Close(playerid);
  472. }
  473. #if defined MS_OnPlayerDisconnect
  474. return MS_OnPlayerDisconnect(playerid, reason);
  475. #else
  476. return 1;
  477. #endif
  478. }
  479. #if defined _ALS_OnPlayerDisconnect
  480. #undef OnPlayerDisconnect
  481. #else
  482. #define _ALS_OnPlayerDisconnect
  483. #endif
  484. #define OnPlayerDisconnect MS_OnPlayerDisconnect
  485. #if defined MS_OnPlayerDisconnect
  486. forward MS_OnPlayerDisconnect(playerid, reason);
  487. #endif
  488. /*
  489. OnPlayerClickPlayerTextDraw
  490. */
  491. public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
  492. {
  493. if (MSelect_IsOpen(playerid)) {
  494. new MSelectType:response_type = MSelect_None;
  495. // check buttons
  496. if (TD_ButtonCancel[playerid] == playertextid) {
  497. response_type = MSelect_Button;
  498. } else if (TD_ButtonPrev[playerid] == playertextid) {
  499. if (ListLoop[playerid] || ListPage[playerid] != 0) {
  500. ListPage[playerid]--;
  501. TD_SetPage(playerid, ListPage[playerid], TD_ItemsModel[playerid], ItemsCount[playerid],
  502. ListLoop[playerid], TD_PosX[playerid], TD_PosY[playerid],
  503. TD_RotX[playerid], TD_RotY[playerid], TD_RotZ[playerid], TD_Zoom[playerid],
  504. TD_ItemWidth[playerid], TD_ItemHeight[playerid],
  505. TD_PaddingBackground[playerid], TD_PaddingItem[playerid], TD_PaddingPage[playerid],
  506. TD_ItemsBgColors[playerid], TD_PageFgColor[playerid]);
  507. response_type = MSelect_ButtonPrev;
  508. }
  509. } else if (TD_ButtonNext[playerid] == playertextid) {
  510. new max_page;
  511. GetPaginatorInfo(ItemsCount[playerid], .max_page = max_page);
  512. if (ListLoop[playerid] || ListPage[playerid] != max_page - 1) {
  513. ListPage[playerid]++;
  514. TD_SetPage(playerid, ListPage[playerid], TD_ItemsModel[playerid], ItemsCount[playerid],
  515. ListLoop[playerid], TD_PosX[playerid], TD_PosY[playerid],
  516. TD_RotX[playerid], TD_RotY[playerid], TD_RotZ[playerid], TD_Zoom[playerid],
  517. TD_ItemWidth[playerid], TD_ItemHeight[playerid],
  518. TD_PaddingBackground[playerid], TD_PaddingItem[playerid], TD_PaddingPage[playerid],
  519. TD_ItemsBgColors[playerid], TD_PageFgColor[playerid]);
  520. response_type = MSelect_ButtonNext;
  521. }
  522. }
  523. // check listitem
  524. for (new i = 0; i < ItemsCount[playerid]; i++) {
  525. if (TD_Item[playerid][i] == playertextid) {
  526. TD_SelectItem(playerid, i);
  527. response_type = MSelect_Item;
  528. break;
  529. }
  530. }
  531. // check on errors
  532. if (response_type == MSelect_None) {
  533. #if defined MS_OnPlayerClickPlayerTextDraw
  534. return MS_OnPlayerClickPlayerTextDraw(playerid, playertextid);
  535. #else
  536. return 0;
  537. #endif
  538. }
  539. // check list_id
  540. new list_id = ListItemID[playerid];
  541. if (ListItemPage[playerid] != ListPage[playerid]) {
  542. list_id = -1;
  543. }
  544. // close the menu
  545. if (response_type == MSelect_Button) {
  546. MSelect_Close(playerid);
  547. }
  548. // call function
  549. new call_func[MSELECT_MAX_FUNCTION_NAME] = "msr_";
  550. strcat(call_func, FunctionName[playerid]);
  551. if (funcidx(call_func) != -1) {
  552. CallLocalFunction(call_func, "iiii", playerid, _:response_type, list_id, ListItemModel[playerid]);
  553. }
  554. return 1;
  555. }
  556. #if defined MS_OnPlayerClickPlayerTextDraw
  557. return MS_OnPlayerClickPlayerTextDraw(playerid, playertextid);
  558. #else
  559. return 0;
  560. #endif
  561. }
  562. #if defined _ALS_OnPlayerClickPlayerTD
  563. #undef OnPlayerClickPlayerTextDraw
  564. #else
  565. #define _ALS_OnPlayerClickPlayerTD
  566. #endif
  567. #define OnPlayerClickPlayerTextDraw MS_OnPlayerClickPlayerTextDraw
  568. #if defined MS_OnPlayerClickPlayerTextDraw
  569. forward MS_OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid);
  570. #endif
  571. /*
  572. OnPlayerClickTextDraw
  573. */
  574. public OnPlayerClickTextDraw(playerid, Text:clickedid)
  575. {
  576. if (clickedid == Text:INVALID_TEXT_DRAW && TD_SkipCancel[playerid]) {
  577. TD_SkipCancel[playerid] = false;
  578. return 1;
  579. }
  580. if (clickedid == Text:INVALID_TEXT_DRAW && MSelect_IsOpen(playerid)) {
  581. // close the menu
  582. MSelect_Close(playerid);
  583. // call the function
  584. new call_func[MSELECT_MAX_FUNCTION_NAME] = "msr_";
  585. strcat(call_func, FunctionName[playerid]);
  586. if (funcidx(call_func) != -1) {
  587. CallLocalFunction(call_func, "iiii", playerid, _:MSelect_Cancel, ListItemID[playerid], ListItemModel[playerid]);
  588. }
  589. return 1;
  590. }
  591. #if defined MS_OnPlayerClickTextDraw
  592. return MS_OnPlayerClickTextDraw(playerid, Text:clickedid);
  593. #else
  594. return 0;
  595. #endif
  596. }
  597. #if defined _ALS_OnPlayerClickTextDraw
  598. #undef OnPlayerClickTextDraw
  599. #else
  600. #define _ALS_OnPlayerClickTextDraw
  601. #endif
  602. #define OnPlayerClickTextDraw MS_OnPlayerClickTextDraw
  603. #if defined MS_OnPlayerClickTextDraw
  604. forward MS_OnPlayerClickTextDraw(playerid, Text:clickedid);
  605. #endif
  606. /*
  607. Helpers
  608. */
  609. static stock MS_strcpy(result[], source[], const size = sizeof(result))
  610. {
  611. result[0] = 0;
  612. return strcat(result, source, size);
  613. }