├── README.md
├── YSI
├── YSI-Includes-5.x.zip
├── amx_assembly-master.zip
├── code-parse.inc-master.zip
└── indirection-master.zip
├── dialog-pages(v2.1).inc
├── dialogpages-test.pwn
├── example.pwn
└── zeex Compilator 3.10.10
└── pawnc-3.10.10-windows.zip
/README.md:
--------------------------------------------------------------------------------
1 | # 🥇 Dynamic Dialog-Pages for San Andreas MultiPlayer
2 |
3 | Using this library you will can create pages in dialogs with a few lines of code. You can display many more lines in the dialog aside from the 4096 character limit using pages.
4 |
5 |
6 |
7 | > Let's see how it's working.
8 |
9 | ### First of all init include for your gamemode.
10 | ```pawn
11 | #include "dialog-pages.inc"
12 | ```
13 | > The addition of the YSI library is required for Dialog-Pages to function properly. YSI has been added to the repository and the necessary files (compilator etc.)
14 |
15 | To create dialog-pages you must use this function. This function have more arguments than the orginal. Additional arguments add library hints how the dialog exactly should look.
16 | ```pawn
17 | ShowPlayerDialogPages(playerid, dialogid, dialogstyle, caption[], info[], button1[], button2[], maxitemslist = 15, nextbutton[] = "Next page", lastbutton[] = "Previous page", bool:dynamic = false);
18 | ```
19 | - **playerid** - player ID.
20 | - **dialogid** - dialog ID to check action.
21 | - **dialogstyle** - dialog format: *DIALOG_STYLE_LIST, DIALOG_STYLE_TABLIST, DIALOG_STYLE_TABLIST_HEADERS*
22 | - **caption[]** - title string dialog.
23 | - **info[]** - main string content dialog.
24 | - **button1[]** - string content for first button.
25 | - **button2[]** - string content for last button.
26 | - **maxitemlist** - number of lines for one page.
27 | - **nextbutton[]** - string content for next page button.
28 | - **lastbutton[]** - string content for previous page button.
29 | - **bool:dynamic** - if you would control dialog manualy (mainly buttons for page changes) you can set this boolean to true. If you use dynamic dialog-pages you must assign the action by yourself to the buttons chaning pages. If set to false, the include assign the page change button itself without your interference. You can learn more about dynamic dialogs below.
30 |
31 | Dialog-Pages cooperates with large strings which means you can enter whatever you want. Now you can fit a lot of content into one dialog.
32 |
33 | To check the action for dialog-pages use the initialized function in the library:
34 |
35 | ```pawn
36 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index)
37 | ```
38 | - **playerid** - player ID.
39 | - **dialogid** - dialog ID for check specific dialog.
40 | - **response** - returns true/false depending on which button is clicked in the dialog box.
41 | - **listitem** - return the index of the row clicked depending on the page.
42 | - **inputtext[]** - return a content of clicked listitem.
43 | - **btn_next_index** - return the index of the next button that changes page.
44 | - **btn_previous_index** - return the index of the previous button that changes page.
45 |
46 | **The last two arguments of this public are only useful when you indicate that the selecyed dialog is dynamic. With two arguments, you are able to check if one of the page change buttons has been clicked.**
47 |
48 | ## 📄 Let's see how to create a dialog which isn't dynamic. 📄
49 | > Let's create a loop which will generate for example 100 lines and put it into dialog. Let's make dialog which designate that there're only 10 lines per page. We can estimate that if we have 100 lines and divide it into 10 possible lines in one page in dialog there will be 10 pages - because **10 * 10 = 100**
50 | ```pawn
51 | new string[4096], tmp_str[64];
52 | for(new i = 0; i < 100; i++)
53 | {
54 | format(tmp_str, sizeof tmp_str, "Random number: %i\n", random(999));
55 | strcat(string, tmp_str);
56 | }
57 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Dialog-Pages - Test.", string, "Select", "Cancel", 10, "Next page", "Previous Page", false);
58 | ```
59 | > If your intention isn't to create a dynamic dialog, you don't need to set the last argument because the default value is false.
60 | ```pawn
61 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Dialog-Pages - Test.", string, "Select", "Cancel", 10, "Next page", "Previous Page");
62 | ```
63 | > The same goes for the buttons chaning pages. If you don't want to change them, you can just skip the arguments last three arguments:
64 | ```pawn
65 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Dialog-Pages - Test.", string, "Select", "Cancel", 10);
66 | ```
67 | > Also, you don't need to enter the number of lines per page. The default is 15.
68 | ```pawn
69 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Dialog-Pages - Test.", string, "Select", "Cancel");
70 | ```
71 | See how easy it is to use this library!
72 |
73 | #### Let's check how to refer to the dialog. Let us make that after clicking the "Select" button then server send message for player with the index that was selected on the page in the dialog when will be displayed.
74 | ```pawn
75 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index)
76 | {
77 | switch(dialogid)
78 | {
79 | case 9812: //ID of dialog which we checking.
80 | {
81 | if(response)
82 | {
83 | new string[128];
84 | format(string, sizeof string, "You selected row: %i", listitem);
85 | SendClientMessage(playerid, -1, string);
86 | }
87 | }
88 | }
89 | return 1;
90 | }
91 | ```
92 |
93 | Ready. In this way, we have created a dialog with the pages that sends a message to the client who exactly clicked the index with the "Select" button.
94 |
95 | ## 📑 Let's see how to create a dialog which is dynamic. 📑
96 | > We will create the same dialog as above, only that it will be dynamic. We set ``bool:dynamic`` to **true** (in this case we have to give all the arguments in the function).
97 | ```pawn
98 | new string[4096], tmp_str[64];
99 | for(new i = 0; i < 100; i++)
100 | {
101 | format(tmp_str, sizeof tmp_str, "Random number: %i\n", random(999));
102 | strcat(string, tmp_str);
103 | }
104 | ShowPlayerDialogPages(playerid, 9700, DIALOG_STYLE_LIST, "Dialog-Pages - Test.", string, "Select", "Cancel", 10, "Next page", "Previous Page", true);
105 | ```
106 | When you using dynamic dialogs, you are forced to add an action for page buttons on the your code. To give them an action, you need to use the OnDialogPagesResponse callback and check which button has been clicked. For this condition, you will need the last two callback parameters. Just see 109 line:
107 | ```pawn
108 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index)
109 | {
110 | switch(dialogid)
111 | {
112 | case 9700:
113 | {
114 | if(listitem == btn_next_index || listitem == btn_previous_index) //line 109
115 | {
116 | if(listitem == btn_next_index)
117 | ShowPlayerDialogNextPage(playerid);
118 | else ShowPlayerDialogPreviousPage(playerid);
119 | }
120 | else ClearDialogPagesData(playerid); //line 115
121 | }
122 | }
123 | return 1;
124 | }
125 | ```
126 | This code above checks to see if one of the page change buttons is clicked and gives them the same action that the include gives by default.
127 |
128 | > Functions for manage a dynamic dialogs below:
129 | ```pawn
130 | ShowPlayerDialogNextPage(playerid); //- open a next page if the next page exist.
131 | ShowPlayerDialogPreviousPage(playerid); //- open a previous page if previous page exist.
132 | ShowPlayerDialogCurrentPage(playerid); //- open a current page.
133 | ClearDialogPagesData(playerid); //- clearing all data dialog-pages for player.
134 | ```
135 |
136 | > Definitions:
137 | ```pawn
138 | #define INVALID_BUTTON_ID -1
139 | ```
140 |
141 | > An important element is the reset of dialog data. If you are using dynamic dialogs you are forced to reset the data after the dialog is completely closed. You must always keep this in mind as data cleansing is only required in dynamic dialogs.
142 |
143 | > Look at 115 line, if player wasn't clicked button for changing pages he must clicked a normal list so you will be forced to reset dialog data for player because if player click on the normal list, the dialog is completely closed.
144 |
145 | If we wanted to do exactly the same as in the static dialog above, we should code it this way in OnDialogPagesResponse.
146 | ```pawn
147 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index)
148 | {
149 | switch(dialogid)
150 | {
151 | case 9700:
152 | {
153 | if(listitem == btn_next_index || listitem == btn_previous_index)
154 | {
155 | if(listitem == btn_next_index)
156 | ShowPlayerDialogNextPage(playerid);
157 | else ShowPlayerDialogPreviousPage(playerid);
158 | }
159 | else
160 | {
161 | if(response)
162 | {
163 | new string[128];
164 | format(string, sizeof string, "You selected row: %i", listitem);
165 | SendClientMessage(playerid, -1, string);
166 | }
167 | ClearDialogPagesData(playerid); //remember to reset player data if dialog completely closed.
168 | }
169 | }
170 | }
171 | return 1;
172 | }
173 | ```
174 |
175 | > Creating dynamic dialogs is very important for people who want to change actions for buttons that change page. Coding them is very simple and simple to operate. This way you can edit the action of the buttons.
176 |
177 | ## Display of the current page or the maximum number of pages in caption or info.
178 | > By placing the appropriate phrases, which are given below in the title or in the main text, you are able to display the current page viewed or the number of all generated pages by Dialog-Pages.
179 | ```
180 | #currentpage - display a current page.
181 | #pagelist - display a all list of pages.
182 | ```
183 |
184 | Example:
185 | ```pawn
186 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Test dialog. (Page: #currentpage/#pagelist)", string, "Select", "Cancel");
187 | ```
188 |
189 |

190 |
191 |

192 |
193 |
194 | ## #pragma - most possible error.
195 | > It is possible that you will have to use #pragma dynamic. This is the fault of exceeding the data buffering barrier. If the server does not start and the code compiles, increase cells to #pragma dynamic
196 |
197 | ## Feedback and contact with library autors:
198 | - Author of this include is Robson04. If you would contact with me, you can find me in discord: **Robson04#8010**
199 |
--------------------------------------------------------------------------------
/YSI/YSI-Includes-5.x.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robson04/dialog-pages/fb5cc8cfdc39823ef4b04fc60cf9b5b78316cd8e/YSI/YSI-Includes-5.x.zip
--------------------------------------------------------------------------------
/YSI/amx_assembly-master.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robson04/dialog-pages/fb5cc8cfdc39823ef4b04fc60cf9b5b78316cd8e/YSI/amx_assembly-master.zip
--------------------------------------------------------------------------------
/YSI/code-parse.inc-master.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robson04/dialog-pages/fb5cc8cfdc39823ef4b04fc60cf9b5b78316cd8e/YSI/code-parse.inc-master.zip
--------------------------------------------------------------------------------
/YSI/indirection-master.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robson04/dialog-pages/fb5cc8cfdc39823ef4b04fc60cf9b5b78316cd8e/YSI/indirection-master.zip
--------------------------------------------------------------------------------
/dialog-pages(v2.1).inc:
--------------------------------------------------------------------------------
1 | /*
2 | Dialog Pages V2.0
3 | Author: Robson04
4 | */
5 |
6 | #include "a_samp"
7 | #include "YSI_Coding\y_hooks"
8 |
9 | #define MAX_DIALOG_CAPTION_LEN (64)
10 | #define MAX_DIALOG_HEADER_LEN (512)
11 | #define MAX_DIALOG_INFO_LEN (8192)
12 | #define MAX_DIALOG_BUTTON_LEN (128)
13 |
14 | #define BUTTON_NEXT_PAGE 0
15 | #define BUTTON_PREVIOUS_PAGE 1
16 | #define INVALID_BUTTON_ID -1
17 |
18 | #define DIALOG_PAGES_CAPTION 0
19 | #define DIALOG_PAGES_INFO 1
20 |
21 | forward bool:IsButtonUsed(playerid, buttontype);
22 | forward OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index);
23 |
24 | enum DIALOG_PAGES
25 | {
26 | bool:IsDialogActivate,
27 | DialogID,
28 | DialogStyle,
29 | Caption[MAX_DIALOG_CAPTION_LEN],
30 | Info[MAX_DIALOG_INFO_LEN],
31 | Button1[MAX_DIALOG_BUTTON_LEN],
32 | Button2[MAX_DIALOG_BUTTON_LEN],
33 | NextButton[MAX_DIALOG_BUTTON_LEN],
34 | LastButton[MAX_DIALOG_BUTTON_LEN],
35 |
36 | ItemCount,
37 | CurrentPage,
38 | MaxItemsSplit,
39 | PagesList,
40 | Header[MAX_DIALOG_HEADER_LEN],
41 | TabList,
42 | bool:IsDynamic
43 | };
44 | new PlayerDialogPagesCache[MAX_PLAYERS][DIALOG_PAGES];
45 |
46 | hook OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
47 | {
48 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
49 | {
50 | if(dialogid == PlayerDialogPagesCache[playerid][DialogID])
51 | {
52 | new button_next = INVALID_BUTTON_ID, button_previous = INVALID_BUTTON_ID;
53 | if(IsDialogPagesButtonUsed(playerid, BUTTON_NEXT_PAGE))
54 | button_next = (GetDialogPagesListItemCount(playerid) - 1) + 1;
55 | if(IsDialogPagesButtonUsed(playerid, BUTTON_PREVIOUS_PAGE))
56 | {
57 | if(IsDialogPagesButtonUsed(playerid, BUTTON_NEXT_PAGE))
58 | button_previous = (GetDialogPagesListItemCount(playerid) - 1) + 2;
59 | else button_previous = (GetDialogPagesListItemCount(playerid) - 1) + 1;
60 | }
61 |
62 | if(listitem == button_next || listitem == button_previous)
63 | {
64 | if(listitem == button_next)
65 | {
66 | if(PlayerDialogPagesCache[playerid][IsDynamic] == false)
67 | ShowPlayerDialogNextPage(playerid);
68 | else
69 | {
70 | new edited_listitem = 0;
71 | if(PlayerDialogPagesCache[playerid][CurrentPage] == 1)
72 | {
73 | edited_listitem = listitem;
74 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, button_next, button_previous);
75 | }
76 | else
77 | {
78 | new page_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit], tmp_btn_next = page_listitems + button_next, tmp_btn_prev = page_listitems + button_previous;
79 | edited_listitem = page_listitems + listitem;
80 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, tmp_btn_next, tmp_btn_prev);
81 | }
82 | }
83 | }
84 | else if(listitem == button_previous)
85 | {
86 | if(PlayerDialogPagesCache[playerid][IsDynamic] == false)
87 | ShowPlayerDialogPreviousPage(playerid);
88 | else
89 | {
90 | new edited_listitem = 0;
91 | if(PlayerDialogPagesCache[playerid][CurrentPage] == 1)
92 | {
93 | edited_listitem = listitem;
94 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, button_next, button_previous);
95 | }
96 | else
97 | {
98 | new page_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit], tmp_btn_next = page_listitems + button_next, tmp_btn_prev = page_listitems + button_previous;
99 | edited_listitem = page_listitems + listitem;
100 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, tmp_btn_next, tmp_btn_prev);
101 | }
102 | }
103 | }
104 | }
105 | else
106 | {
107 | new edited_listitem = 0;
108 | if(PlayerDialogPagesCache[playerid][CurrentPage] == 1)
109 | {
110 | edited_listitem = listitem;
111 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, button_next, button_previous);
112 | ClearDialogPagesData(playerid);
113 | }
114 | else
115 | {
116 | new page_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit], tmp_btn_next = page_listitems + button_next, tmp_btn_prev = page_listitems + button_previous;
117 | edited_listitem = page_listitems + listitem;
118 | OnDialogPagesResponse(playerid, dialogid, response, edited_listitem, inputtext, tmp_btn_next, tmp_btn_prev);
119 | ClearDialogPagesData(playerid);
120 | }
121 | }
122 | }
123 | else ClearDialogPagesData(playerid);
124 | }
125 | return 0;
126 | }
127 |
128 | stock ShowPlayerDialogPages(playerid, dialogid, dialogstyle, const caption[], info[], const button1[], const button2[], maxitemslist = 15, const nextbutton[] = "Next page", const lastbutton[] = "Previous page", bool:dynamic = false)
129 | {
130 | ClearDialogPagesData(playerid);
131 | PlayerDialogPagesCache[playerid][DialogID] = dialogid;
132 | PlayerDialogPagesCache[playerid][DialogStyle] = dialogstyle;
133 | format(PlayerDialogPagesCache[playerid][Caption], MAX_DIALOG_CAPTION_LEN, caption);
134 |
135 | if(dialogstyle == DIALOG_STYLE_TABLIST)
136 | {
137 | new header[MAX_DIALOG_HEADER_LEN], findbacknd = strfind(info, "\n", true, 0), tablist_pos = -1;
138 | strmid(header, info, 0, findbacknd + 1);
139 | for(;;)
140 | {
141 | tablist_pos = strfind(header, "\t", true, tablist_pos + 1);
142 | if(tablist_pos == -1) break;
143 | else PlayerDialogPagesCache[playerid][TabList]++;
144 | }
145 | }
146 | else if(dialogstyle == DIALOG_STYLE_TABLIST_HEADERS)
147 | {
148 | new findbacknd = strfind(info, "\n", true, 0), tablist_pos = -1;
149 | strmid(PlayerDialogPagesCache[playerid][Header], info, 0, findbacknd + 1);
150 | for(;;)
151 | {
152 | tablist_pos = strfind(PlayerDialogPagesCache[playerid][Header], "\t", true, tablist_pos + 1);
153 | if(tablist_pos == -1) break;
154 | else PlayerDialogPagesCache[playerid][TabList]++;
155 | }
156 | strdel(info, 0, findbacknd + 1);
157 | }
158 |
159 | new tmp_str[6];
160 | strmid(tmp_str, info, strlen(info) - 1, strlen(info));
161 | if(strcmp(tmp_str, "\n", true) != 0) strcat(info, "\n", MAX_DIALOG_INFO_LEN);
162 | strcat(PlayerDialogPagesCache[playerid][Info], info);
163 |
164 | format(PlayerDialogPagesCache[playerid][Button1], MAX_DIALOG_BUTTON_LEN, button1);
165 | format(PlayerDialogPagesCache[playerid][Button2], MAX_DIALOG_BUTTON_LEN, button2);
166 | format(PlayerDialogPagesCache[playerid][NextButton], MAX_DIALOG_BUTTON_LEN, nextbutton);
167 | format(PlayerDialogPagesCache[playerid][LastButton], MAX_DIALOG_BUTTON_LEN, lastbutton);
168 | PlayerDialogPagesCache[playerid][MaxItemsSplit] = maxitemslist;
169 | PlayerDialogPagesCache[playerid][IsDynamic] = dynamic;
170 |
171 | new pos = -1;
172 | for(;;)
173 | {
174 | pos = strfind(info, "\n", true, pos + 1);
175 | if(pos == -1) break;
176 | else PlayerDialogPagesCache[playerid][ItemCount]++;
177 | }
178 |
179 | new Float:tmp_pages = floatdiv(PlayerDialogPagesCache[playerid][ItemCount], maxitemslist);
180 | PlayerDialogPagesCache[playerid][PagesList] = floatround(tmp_pages, floatround_round);
181 | if(floatfract(tmp_pages) > 0.0 && floatfract(tmp_pages) < 0.5) PlayerDialogPagesCache[playerid][PagesList]++;
182 | if(PlayerDialogPagesCache[playerid][PagesList] == 0) PlayerDialogPagesCache[playerid][PagesList] = 1;
183 | PlayerDialogPagesCache[playerid][CurrentPage] = 1;
184 |
185 | new tmp_info[MAX_DIALOG_INFO_LEN], index = 0, tmp_pos = -1, itemlist_end = -1;
186 | for(;;)
187 | {
188 | tmp_pos = strfind(info, "\n", true, tmp_pos + 1);
189 | if(tmp_pos == -1) break;
190 | else
191 | {
192 | if(index < maxitemslist)
193 | {
194 | itemlist_end = tmp_pos;
195 | index++;
196 | }
197 | else break;
198 | }
199 | }
200 | strmid(tmp_info, info, 0, itemlist_end);
201 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
202 | strins(tmp_info, PlayerDialogPagesCache[playerid][Header], 0);
203 | AddDialogPagesButtons(playerid, tmp_info);
204 |
205 | ShowPlayerDialog(playerid, dialogid, dialogstyle, StringFormatDialogPagesCaption(playerid, PlayerDialogPagesCache[playerid][Caption]), StringFormatDialogPagesInfo(playerid, tmp_info), button1, button2);
206 | PlayerDialogPagesCache[playerid][IsDialogActivate] = true;
207 | return 1;
208 | }
209 |
210 | stock AddDialogPagesButtons(playerid, info[MAX_DIALOG_INFO_LEN])
211 | {
212 | if(PlayerDialogPagesCache[playerid][PagesList] > 1)
213 | {
214 | if(PlayerDialogPagesCache[playerid][PagesList] != PlayerDialogPagesCache[playerid][CurrentPage])
215 | {
216 | new button_next[MAX_DIALOG_BUTTON_LEN + 11] = "", tmp_str[16]; //+ rgb and \n
217 | format(button_next, sizeof button_next, "\n%s", PlayerDialogPagesCache[playerid][NextButton]);
218 | for(new i = PlayerDialogPagesCache[playerid][TabList]; i > 0; i--)
219 | {
220 | format(tmp_str, sizeof tmp_str, "\t{000000}");
221 | strcat(button_next, tmp_str);
222 | }
223 | strcat(info, button_next);
224 | }
225 |
226 | if(PlayerDialogPagesCache[playerid][CurrentPage] != 1)
227 | {
228 | new button_last[MAX_DIALOG_BUTTON_LEN + 11] = "", tmp_str[16]; //+ rgb and \n
229 | format(button_last, sizeof button_last, "\n%s", PlayerDialogPagesCache[playerid][LastButton]);
230 | for(new i = PlayerDialogPagesCache[playerid][TabList]; i >= 0; i--)
231 | {
232 | format(tmp_str, sizeof tmp_str, "\t{000000}");
233 | strcat(button_last, tmp_str);
234 | }
235 | strcat(info, button_last);
236 | }
237 | }
238 | return 1;
239 | }
240 |
241 | stock ShowPlayerDialogNextPage(playerid)
242 | {
243 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
244 | {
245 | if(PlayerDialogPagesCache[playerid][PagesList] > PlayerDialogPagesCache[playerid][CurrentPage])
246 | {
247 | PlayerDialogPagesCache[playerid][CurrentPage]++;
248 | new tmp_info[MAX_DIALOG_INFO_LEN], previous_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit],
249 | start_pos = -1, end_pos = -1;
250 | new tmp_pos = -1, index = 0;
251 | for(;;)
252 | {
253 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
254 | if(tmp_pos == -1) break;
255 | else
256 | {
257 | if(index < previous_listitems)
258 | {
259 | start_pos = tmp_pos;
260 | index++;
261 | }
262 | else break;
263 | }
264 | }
265 |
266 | tmp_pos = start_pos; index = 0;
267 | for(;;)
268 | {
269 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
270 | if(tmp_pos == -1) break;
271 | else
272 | {
273 | if(index < PlayerDialogPagesCache[playerid][MaxItemsSplit])
274 | {
275 | end_pos = tmp_pos;
276 | index++;
277 | }
278 | else break;
279 | }
280 | }
281 | strmid(tmp_info, PlayerDialogPagesCache[playerid][Info], start_pos + 1, end_pos);
282 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
283 | strins(tmp_info, PlayerDialogPagesCache[playerid][Header], 0);
284 | AddDialogPagesButtons(playerid, tmp_info);
285 |
286 | ShowPlayerDialog(playerid, PlayerDialogPagesCache[playerid][DialogID], PlayerDialogPagesCache[playerid][DialogStyle], StringFormatDialogPagesCaption(playerid, PlayerDialogPagesCache[playerid][Caption]), StringFormatDialogPagesInfo(playerid, tmp_info), PlayerDialogPagesCache[playerid][Button1], PlayerDialogPagesCache[playerid][Button2]);
287 | }
288 | else ShowPlayerDialogCurrentPage(playerid);
289 | }
290 | return 1;
291 | }
292 |
293 | stock ShowPlayerDialogPreviousPage(playerid)
294 | {
295 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
296 | {
297 | if(PlayerDialogPagesCache[playerid][PagesList] - PlayerDialogPagesCache[playerid][CurrentPage] >= 0 && PlayerDialogPagesCache[playerid][CurrentPage] != 1)
298 | {
299 | PlayerDialogPagesCache[playerid][CurrentPage]--;
300 | new tmp_info[MAX_DIALOG_INFO_LEN], previous_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit],
301 | start_pos = -1, end_pos = -1;
302 | new tmp_pos = -1, index = 0;
303 | for(;;)
304 | {
305 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
306 | if(tmp_pos == -1) break;
307 | else
308 | {
309 | if(index < previous_listitems)
310 | {
311 | start_pos = tmp_pos;
312 | index++;
313 | }
314 | else break;
315 | }
316 | }
317 |
318 | tmp_pos = start_pos; index = 0;
319 | for(;;)
320 | {
321 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
322 | if(tmp_pos == -1) break;
323 | else
324 | {
325 | if(index < PlayerDialogPagesCache[playerid][MaxItemsSplit])
326 | {
327 | end_pos = tmp_pos;
328 | index++;
329 | }
330 | else break;
331 | }
332 | }
333 | strmid(tmp_info, PlayerDialogPagesCache[playerid][Info], start_pos + 1, end_pos);
334 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
335 | strins(tmp_info, PlayerDialogPagesCache[playerid][Header], 0);
336 | AddDialogPagesButtons(playerid, tmp_info);
337 |
338 | ShowPlayerDialog(playerid, PlayerDialogPagesCache[playerid][DialogID], PlayerDialogPagesCache[playerid][DialogStyle], StringFormatDialogPagesCaption(playerid, PlayerDialogPagesCache[playerid][Caption]), StringFormatDialogPagesInfo(playerid, tmp_info), PlayerDialogPagesCache[playerid][Button1], PlayerDialogPagesCache[playerid][Button2]);
339 | }
340 | else ShowPlayerDialogCurrentPage(playerid);
341 | }
342 | return 1;
343 | }
344 |
345 | stock ShowPlayerDialogCurrentPage(playerid)
346 | {
347 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
348 | {
349 | if(PlayerDialogPagesCache[playerid][CurrentPage] == 1)
350 | {
351 | new tmp_info[MAX_DIALOG_INFO_LEN], index = 0, itemlist_end = -1;
352 | for(;;)
353 | {
354 | if(index < PlayerDialogPagesCache[playerid][MaxItemsSplit])
355 | {
356 | itemlist_end = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, itemlist_end + 1);
357 | index++;
358 | }
359 | else break;
360 | }
361 | strmid(tmp_info, PlayerDialogPagesCache[playerid][Info], 0, itemlist_end + 1);
362 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
363 | strins(tmp_info, PlayerDialogPagesCache[playerid][Header], 0);
364 | AddDialogPagesButtons(playerid, tmp_info);
365 |
366 | ShowPlayerDialog(playerid, PlayerDialogPagesCache[playerid][DialogID], PlayerDialogPagesCache[playerid][DialogStyle], StringFormatDialogPagesCaption(playerid, PlayerDialogPagesCache[playerid][Caption]), StringFormatDialogPagesInfo(playerid, tmp_info), PlayerDialogPagesCache[playerid][Button1], PlayerDialogPagesCache[playerid][Button2]);
367 | }
368 | else
369 | {
370 | new listitem_count = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit],
371 | tmp_info[MAX_DIALOG_INFO_LEN], start_pos = -1, end_pos = -1;
372 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
373 | strcat(tmp_info, PlayerDialogPagesCache[playerid][Header]);
374 |
375 | new tmp_pos = -1, index = 0;
376 | for(;;)
377 | {
378 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
379 | if(tmp_pos == -1) break;
380 | else
381 | {
382 | if(index < listitem_count)
383 | {
384 | start_pos = tmp_pos;
385 | index++;
386 | }
387 | else break;
388 | }
389 | }
390 |
391 | tmp_pos = start_pos; index = 0;
392 | for(;;)
393 | {
394 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
395 | if(tmp_pos == -1) break;
396 | else
397 | {
398 | if(index < PlayerDialogPagesCache[playerid][MaxItemsSplit])
399 | {
400 | end_pos = tmp_pos;
401 | index++;
402 | }
403 | else break;
404 | }
405 | }
406 | if(start_pos != -1 && end_pos != -1)
407 | {
408 | strmid(tmp_info, PlayerDialogPagesCache[playerid][Info], start_pos + 1, end_pos);
409 | if(PlayerDialogPagesCache[playerid][DialogStyle] == DIALOG_STYLE_TABLIST_HEADERS)
410 | strins(tmp_info, PlayerDialogPagesCache[playerid][Header], 0);
411 | AddDialogPagesButtons(playerid, tmp_info);
412 |
413 | ShowPlayerDialog(playerid, PlayerDialogPagesCache[playerid][DialogID], PlayerDialogPagesCache[playerid][DialogStyle], StringFormatDialogPagesCaption(playerid, PlayerDialogPagesCache[playerid][Caption]), StringFormatDialogPagesInfo(playerid, tmp_info), PlayerDialogPagesCache[playerid][Button1], PlayerDialogPagesCache[playerid][Button2]);
414 | }
415 | else return 0;
416 | }
417 | }
418 | return 1;
419 | }
420 |
421 | stock IsDialogPagesButtonUsed(playerid, buttontype)
422 | {
423 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
424 | {
425 | if(buttontype == BUTTON_NEXT_PAGE)
426 | {
427 | if(PlayerDialogPagesCache[playerid][CurrentPage] >= 1 && PlayerDialogPagesCache[playerid][CurrentPage] != PlayerDialogPagesCache[playerid][PagesList])
428 | return true;
429 | }
430 | else if(buttontype == BUTTON_PREVIOUS_PAGE)
431 | {
432 | if(PlayerDialogPagesCache[playerid][CurrentPage] != 1)
433 | return true;
434 | }
435 | }
436 | return false;
437 | }
438 |
439 | stock ClearDialogPagesData(playerid)
440 | {
441 | new tmp_enum[DIALOG_PAGES];
442 | PlayerDialogPagesCache[playerid] = tmp_enum;
443 | return 1;
444 | }
445 |
446 | stock GetDialogPagesListItemCount(playerid)
447 | {
448 | if(PlayerDialogPagesCache[playerid][IsDialogActivate] == true)
449 | {
450 | if(PlayerDialogPagesCache[playerid][CurrentPage] == 1)
451 | {
452 | new pos = -1, item_count = 0;
453 | for(;;)
454 | {
455 | pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, pos + 1);
456 | if(pos == -1) break;
457 | else
458 | {
459 | if(item_count < PlayerDialogPagesCache[playerid][MaxItemsSplit])
460 | item_count++;
461 | else break;
462 | }
463 | }
464 | return item_count;
465 | }
466 | else
467 | {
468 | new page_listitems = (PlayerDialogPagesCache[playerid][CurrentPage] - 1) * PlayerDialogPagesCache[playerid][MaxItemsSplit],
469 | start_pos = -1, listitem_count = 0;
470 |
471 | new tmp_pos = -1, index = 0;
472 | for(;;)
473 | {
474 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
475 | if(tmp_pos == -1) break;
476 | else
477 | {
478 | if(index < page_listitems)
479 | {
480 | start_pos = tmp_pos;
481 | index++;
482 | }
483 | else break;
484 | }
485 | }
486 |
487 | tmp_pos = start_pos; index = 0;
488 | for(;;)
489 | {
490 | tmp_pos = strfind(PlayerDialogPagesCache[playerid][Info], "\n", true, tmp_pos + 1);
491 | if(tmp_pos == -1) break;
492 | else
493 | {
494 | if(index < PlayerDialogPagesCache[playerid][MaxItemsSplit])
495 | {
496 | listitem_count++;
497 | index++;
498 | }
499 | else break;
500 | }
501 | }
502 | return listitem_count;
503 | }
504 | }
505 | return -1;
506 | }
507 |
508 | stock StringFormatDialogPagesInfo(playerid, const text[])
509 | {
510 | new info[MAX_DIALOG_INFO_LEN];
511 | strcat(info, text);
512 |
513 | new info_pos = 0, info_lastfind = 0;
514 | for(;;)
515 | {
516 | info_pos = strfind(info, "#currentpage", true, info_lastfind);
517 | if(info_pos == -1) break;
518 | else
519 | {
520 | new string[64];
521 | format(string, sizeof string, "%i", PlayerDialogPagesCache[playerid][CurrentPage]);
522 |
523 | strdel(info, info_pos, info_pos + 12);
524 | strins(info, string, info_pos, MAX_DIALOG_INFO_LEN);
525 | info_lastfind = info_pos + 12;
526 | }
527 | }
528 |
529 | info_pos = 0; info_lastfind = 0;
530 | for(;;)
531 | {
532 | info_pos = strfind(info, "#pagelist", true, info_lastfind);
533 | if(info_pos == -1) break;
534 | else
535 | {
536 | new string[64];
537 | format(string, sizeof string, "%i", PlayerDialogPagesCache[playerid][PagesList]);
538 |
539 | strdel(info, info_pos, info_pos + 9);
540 | strins(info, string, info_pos, MAX_DIALOG_INFO_LEN);
541 | info_lastfind = info_pos + 8;
542 | }
543 | }
544 | return info;
545 | }
546 |
547 | stock StringFormatDialogPagesCaption(playerid, const text[])
548 | {
549 | new caption[MAX_DIALOG_CAPTION_LEN];
550 | strcat(caption, text);
551 |
552 | new caption_pos = 0, caption_lastfind = 0;
553 | for(;;)
554 | {
555 | caption_pos = strfind(caption, "#currentpage", true, caption_lastfind);
556 | if(caption_pos == -1) break;
557 | else
558 | {
559 | new string[64];
560 | format(string, sizeof string, "%i", PlayerDialogPagesCache[playerid][CurrentPage]);
561 |
562 | strdel(caption, caption_pos, caption_pos + 12);
563 | strins(caption, string, caption_pos, MAX_DIALOG_CAPTION_LEN);
564 | caption_lastfind = caption_pos + 12;
565 | }
566 | }
567 |
568 | caption_pos = 0; caption_lastfind = 0;
569 | for(;;)
570 | {
571 | caption_pos = strfind(caption, "#pagelist", true, caption_lastfind);
572 | if(caption_pos == -1) break;
573 | else
574 | {
575 | new string[64];
576 | format(string, sizeof string, "%i", PlayerDialogPagesCache[playerid][PagesList]);
577 |
578 | strdel(caption, caption_pos, caption_pos + 9);
579 | strins(caption, string, caption_pos, MAX_DIALOG_CAPTION_LEN);
580 | caption_lastfind = caption_pos + 8;
581 | }
582 | }
583 | return caption;
584 | }
585 |
--------------------------------------------------------------------------------
/dialogpages-test.pwn:
--------------------------------------------------------------------------------
1 | #include "a_samp.inc"
2 | #include "../include/dialog-pages.inc"
3 | #include "zcmd.inc"
4 |
5 | #pragma dynamic 162940
6 |
7 | #define MECHANIC 0
8 | #define ELECTRICIAN 1
9 | #define TEACHER 2
10 | #define LOCKSMITH 3
11 | #define PLUMBER 4
12 | #define NONE 5
13 | new const Careers[][] =
14 | {
15 | {MECHANIC, "{F6FCCF}Mechanic"},
16 | {ELECTRICIAN, "{CFE3FC}Electrician"},
17 | {TEACHER, "{FCCFDA}Teacher"},
18 | {LOCKSMITH, "{D9FCCF}Locksmith"},
19 | {PLUMBER, "{CFFCDF}Plumber"},
20 | {NONE, "{999999}None"}
21 | };
22 |
23 | new const TestDialog[][][] =
24 | {
25 | {
26 | {1, TEACHER, "Monica Washington"},
27 | {2, NONE, "Garrett Ford"},
28 | {3, ELECTRICIAN, "Alexander Baker"},
29 | {4, ELECTRICIAN, "Rosa Wong"},
30 | {5, ELECTRICIAN, "Edmund Jacobs"},
31 | {6, PLUMBER, "Lucy Cannon"},
32 | {7, NONE, "Freda Flowers"},
33 | {8, PLUMBER, "Shane Lowe"},
34 | {9, NONE, "Annette Alexander"},
35 | {10, LOCKSMITH, "Kimberly Craig"},
36 | {11, MECHANIC, "Myron Holland"},
37 | {12, NONE, "Rachel Watts"},
38 | {13, LOCKSMITH, "Vera Oliver"},
39 | {14, MECHANIC, "Sara Burton"},
40 | {15, NONE, "Erin Thompson"},
41 | {16, TEACHER, "Nicole Gordon"},
42 | {17, NONE, "Estelle Crawford"},
43 | {18, LOCKSMITH, "Rodolfo Carson"},
44 | {19, ELECTRICIAN, "Lucia Collins"},
45 | {20, ELECTRICIAN, "Roy Lewis"},
46 | {21, MECHANIC, "Antonia Wagner"},
47 | {22, TEACHER, "Kenneth Sanders"},
48 | {23, LOCKSMITH, "Louis Howell"},
49 | {24, TEACHER, "Taylor Watson"},
50 | {25, MECHANIC, "Mercedes Logan"},
51 | {26, NONE, "Harriet Cox"}
52 | }
53 | };
54 |
55 | CMD:dialogtest1(playerid)
56 | {
57 | new string[4096] = "#\tIdentity\tCareer\n";
58 | for(new i; i < 26; i++)
59 | {
60 | new tmp_str[128], career[32];
61 | for(new j, k = sizeof(Careers); j < k; j++)
62 | {
63 | if(TestDialog[0][i][1] == Careers[j][0])
64 | format(career, sizeof career, Careers[j][1]);
65 | }
66 | format(tmp_str, sizeof tmp_str, "%i\t{4361EA}%s\t%s\n", TestDialog[0][i][0], TestDialog[0][i][2], career);
67 | strcat(string, tmp_str);
68 | }
69 | ShowPlayerDialogPages(playerid, 947, DIALOG_STYLE_TABLIST_HEADERS, "List of professionally active people", string, "Hidden", "", 20, "> Next page", "< Previous Page");
70 | return 1;
71 | }
72 |
73 | CMD:dialogtest2(playerid)
74 | {
75 | new string[4096] = "#\tIdentity\tCareer\n";
76 | for(new i; i < 26; i++)
77 | {
78 | new tmp_str[128], career[32];
79 | for(new j, k = sizeof(Careers); j < k; j++)
80 | {
81 | if(TestDialog[0][i][1] == Careers[j][0])
82 | format(career, sizeof career, Careers[j][1]);
83 | }
84 | format(tmp_str, sizeof tmp_str, "%i\t{4361EA}%s\t%s\n", TestDialog[0][i][0], TestDialog[0][i][2], career);
85 | strcat(string, tmp_str);
86 | }
87 | ShowPlayerDialogPages(playerid, 947, DIALOG_STYLE_TABLIST_HEADERS, "List of professionally active people", string, "Hidden", "", 20, "{FFC300}>>> (#currentpage/#pagelist) >>>", "{FFC300}<<< (#currentpage/#pagelist) <<<");
88 | return 1;
89 | }
90 |
91 | CMD:dialogtest3(playerid)
92 | {
93 | new string[4096] = "# (Page: #currentpage/#pagelist)\tIdentity\tCareer\n";
94 | for(new i; i < 26; i++)
95 | {
96 | new tmp_str[128], career[32];
97 | for(new j, k = sizeof(Careers); j < k; j++)
98 | {
99 | if(TestDialog[0][i][1] == Careers[j][0])
100 | format(career, sizeof career, Careers[j][1]);
101 | }
102 | format(tmp_str, sizeof tmp_str, "%i\t{4361EA}%s\t%s\n", TestDialog[0][i][0], TestDialog[0][i][2], career);
103 | strcat(string, tmp_str);
104 | }
105 | ShowPlayerDialogPages(playerid, 947, DIALOG_STYLE_TABLIST_HEADERS, "List of professionally active people", string, "Hidden", "", 20, "{C70039}• > •", "{C70039}• < •");
106 | return 1;
107 | }
108 |
109 | public OnFilterScriptInit()
110 | {
111 | printf("[Dialog-Pages]: Loaded test dialogs.");
112 | return 1;
113 | }
114 |
115 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[], btn_next_index, btn_previous_index)
116 | {
117 | return 0;
118 | }
119 |
--------------------------------------------------------------------------------
/example.pwn:
--------------------------------------------------------------------------------
1 | public OnDialogPagesResponse(playerid, dialogid, response, listitem, inputtext[])
2 | {
3 | new string[128];
4 | format(string, sizeof string, "[Dialog-Pages Debug] You decided to response = %s. Listitem index = %i.", (response) ? ("true") : ("false"), listitem);
5 | SendClientMessage(playerid, 0xFFF0000, string);
6 | return 1;
7 | }
8 |
9 | public OnPlayerCommandText(playerid, cmdtext[])
10 | {
11 | if(strcmp(cmdtext, "/dialogtest1", true) == 0)
12 | {
13 | //DIALOG_STYLE_LIST
14 | new string[4096], tmp_str[64];
15 | for(new i = 0; i < 100; i++)
16 | {
17 | format(tmp_str, sizeof tmp_str, "Loop row index: %i\n", i);
18 | strcat(string, tmp_str);
19 | }
20 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_LIST, "Dialog-Pages ~ Robson04.", string, "Select", "Cancel", 15);
21 | }
22 | if(strcmp(cmdtext, "/dialogtest2", true) == 0)
23 | {
24 | //DIALOG_STYLE_TABLIST
25 | new string[8192], tmp_str[64];
26 | for(new i = 0; i < 200; i++)
27 | {
28 | format(tmp_str, sizeof tmp_str, "Column 1\tColumn 2\tIndex: %i\n", i);
29 | strcat(string, tmp_str);
30 | }
31 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_TABLIST, "Dialog-Pages ~ Robson04. (Page: #currentpage)", string, "Select", "Cancel", 12, "{A0A0A0}>>>", "{A0A0A0}<<<");
32 | }
33 | if(strcmp(cmdtext, "/dialogtest3", true) == 0)
34 | {
35 | //DIALOG_STYLE_TABLIST_HEADERS
36 | new string[8192] = "Column 1\tColumn 2\tColumn 3\n", tmp_str[64];
37 | for(new i = 0; i < 275; i++)
38 | {
39 | format(tmp_str, sizeof tmp_str, "Hello world\t%x\tIndex: %i\n", random(999999), i);
40 | strcat(string, tmp_str);
41 | }
42 | ShowPlayerDialogPages(playerid, 9812, DIALOG_STYLE_TABLIST_HEADERS, "Dialog-Pages (Page: #currentpage/#pagelist)", string, "Select", "Cancel", 18, "{ff0000}-> Next page", "{000FFF}<- Previous page");
43 | }
44 | return 1;
45 | }
46 |
--------------------------------------------------------------------------------
/zeex Compilator 3.10.10/pawnc-3.10.10-windows.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robson04/dialog-pages/fb5cc8cfdc39823ef4b04fc60cf9b5b78316cd8e/zeex Compilator 3.10.10/pawnc-3.10.10-windows.zip
--------------------------------------------------------------------------------