Atrinik Client  4.0
list.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program 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 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program 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 this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <toolkit/string.h>
34 
40 static void list_draw_frame(list_struct *list)
41 {
42  draw_frame(list->surface, list->x + list->frame_offset, LIST_ROWS_START(list), list->width, LIST_ROWS_HEIGHT(list));
43 }
44 
54 static void list_row_color(list_struct *list, int row, SDL_Rect box)
55 {
56  if (row & 1) {
57  SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x55, 0x55, 0x55));
58  } else {
59  SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x45, 0x45, 0x45));
60  }
61 }
62 
70 static void list_row_highlight(list_struct *list, SDL_Rect box)
71 {
72  SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x00, 0x80, 0x00));
73 }
74 
82 static void list_row_selected(list_struct *list, SDL_Rect box)
83 {
84  SDL_FillRect(list->surface, &box, SDL_MapRGB(list->surface->format, 0x00, 0x00, 0xef));
85 }
86 
96 void list_set_parent(list_struct *list, int px, int py)
97 {
98  list->px = px;
99  list->py = py;
100 }
101 
113 list_struct *list_create(uint32_t max_rows, uint32_t cols, int spacing)
114 {
115  list_struct *list = ecalloc(1, sizeof(list_struct));
116 
117  if (max_rows == 0) {
118  LOG(BUG, "Attempted to create a list with 0 max rows, changing to 1.");
119  max_rows = 1;
120  }
121 
122  /* Store the values. */
123  list->max_rows = max_rows;
124  list->cols = cols;
125  list->spacing = spacing;
126  list->surface = ScreenSurface;
127  list->focus = 1;
128 
129  /* Initialize defaults. */
130  list->frame_offset = -2;
131  list->header_height = 12;
132  list->row_selected = 1;
133 
134  /* Generic functions. */
139 
140  /* Initialize column data. */
141  list->col_widths = ecalloc(1, sizeof(*list->col_widths) * list->cols);
142  list->col_spacings = ecalloc(1, sizeof(*list->col_spacings) * list->cols);
143  list->col_names = ecalloc(1, sizeof(*list->col_names) * list->cols);
144  list->col_centered = ecalloc(1, sizeof(*list->col_centered) * list->cols);
145 
146  list_set_font(list, FONT_SANS10);
147 
148  return list;
149 }
150 
163 void list_add(list_struct *list, uint32_t row, uint32_t col, const char *str)
164 {
165  if (!list) {
166  return;
167  }
168 
169  if (col > list->cols) {
170  LOG(BUG, "Attempted to add column #%u, but columns max is %u.", col, list->cols);
171  return;
172  }
173 
174  /* Add new rows. */
175  if (row + 1 > list->rows) {
176  uint32_t i;
177 
178  /* Update rows count and resize the array of rows. */
179  list->rows = row + 1;
180  list->text = erealloc(list->text, sizeof(*list->text) * list->rows);
181 
182  /* Allocate columns for the new row(s). */
183  for (i = row; i < list->rows; i++) {
184  list->text[i] = ecalloc(1, sizeof(**list->text) * list->cols);
185  }
186  }
187 
188  list->text[row][col] = str ? estrdup(str) : NULL;
189 }
190 
198 void list_remove_row(list_struct *list, uint32_t row)
199 {
200  uint32_t col, row2;
201 
202  /* Sanity checks. */
203  if (!list || !list->text || row >= list->rows) {
204  return;
205  }
206 
207  /* Free the columns of the row that is being removed. */
208  for (col = 0; col < list->cols; col++) {
209  efree(list->text[row][col]);
210  }
211 
212  /* If there are any rows below the one that is being removed, they
213  * need to be moved up. */
214  for (row2 = row + 1; row2 < list->rows; row2++) {
215  for (col = 0; col < list->cols; col++) {
216  list->text[row2 - 1][col] = list->text[row2][col];
217  }
218  }
219 
220  list->rows--;
221  list->text = erealloc(list->text, sizeof(*list->text) * list->rows);
222 
223  list_offsets_ensure(list);
224 }
225 
242 void list_set_column(list_struct *list, uint32_t col, int width, int spacing, const char *name, int centered)
243 {
244  if (col > list->cols) {
245  LOG(BUG, "Attempted to change column #%u, but columns max is %u.", col, list->cols);
246  return;
247  }
248 
249  /* Set width. */
250  if (width != -1) {
251  list->col_widths[col] = width;
252  list->width += width;
253  }
254 
255  /* Set spacing. */
256  if (spacing != -1) {
257  list->col_spacings[col] = spacing;
258  list->width += spacing;
259  }
260 
261  /* Set the column's name. */
262  if (name) {
263  /* There shouldn't be one previously, but just in case. */
264  if (list->col_names[col]) {
265  efree(list->col_names[col]);
266  }
267 
268  list->col_names[col] = estrdup(name);
269  }
270 
271  /* Is the column centered? */
272  if (centered != -1) {
273  list->col_centered[col] = centered;
274  }
275 }
276 
285 {
286  if (list->font != NULL) {
287  font_free(list->font);
288  }
289 
290  if (font != NULL) {
291  FONT_INCREF(font);
292  }
293 
294  list->font = font;
295 }
296 
303 {
304  list->scrollbar_enabled = 1;
305  scrollbar_create(&list->scrollbar, 9, LIST_ROWS_HEIGHT(list) + 1, &list->row_offset, &list->rows, list->max_rows);
306 }
307 
316 {
317  if (!list) {
318  return 0;
319  }
320 
321  if (list->scrollbar_enabled && scrollbar_need_redraw(&list->scrollbar)) {
322  return 1;
323  }
324 
325  return 0;
326 }
327 
337 void list_show(list_struct *list, int x, int y)
338 {
339  uint32_t row, col;
340  int w = 0, extra_width = 0;
341  SDL_Rect box;
342 
343  if (!list) {
344  return;
345  }
346 
347  list->x = x;
348  list->y = y;
349 
350  /* Draw a frame, if needed. */
351  if (list->draw_frame_func) {
352  list->draw_frame_func(list);
353  }
354 
355  /* Draw the column names. */
356  for (col = 0; col < list->cols; col++) {
357  extra_width = 0;
358 
359  /* Center it? */
360  if (list->col_centered[col]) {
361  extra_width = list->col_widths[col] / 2 - text_get_width(list->font, list->col_names[col], 0) / 2;
362  }
363 
364  /* Actually draw the column name. */
365  if (list->col_names[col]) {
366  text_show_shadow(list->surface, list->font, list->col_names[col], list->x + w + extra_width, list->y, list->focus ? COLOR_WHITE : COLOR_GRAY, COLOR_BLACK, 0, NULL);
367  }
368 
369  w += list->col_widths[col] + list->col_spacings[col];
370  }
371 
372  /* Initialize default values for coloring rows. */
373  box.x = list->x + list->frame_offset;
374  box.w = list->width;
375  box.h = LIST_ROW_HEIGHT(list);
376 
377  if (list->scrollbar_enabled) {
378  scrollbar_show(&list->scrollbar, list->surface, list->x + list->frame_offset + 1 + w, LIST_ROWS_START(list));
379  }
380 
381  /* Doing coloring of each row? */
382  if (list->row_color_func) {
383  for (row = 0; row < list->max_rows; row++) {
384  box.y = LIST_ROWS_START(list) + (row * LIST_ROW_HEIGHT(list));
385  list->row_color_func(list, row, box);
386  }
387  }
388 
389  /* Start printing out rows from the offset to the maximum. */
390  for (row = list->row_offset; row < list->rows; row++) {
391  /* Stop if we reached maximum number of visible rows. */
392  if (LIST_ROW_OFFSET(row, list) == list->max_rows) {
393  break;
394  }
395 
396  if (list->row_selected_func && (row + 1) == list->row_selected) {
397  /* Color selected row. */
398  box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list));
399  list->row_selected_func(list, box);
400  } else if (list->row_highlight_func && (row + 1) == list->row_highlighted) {
401  /* Color highlighted row. */
402  box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list));
403  list->row_highlight_func(list, box);
404  }
405 
406  w = 0;
407 
408  /* Show all the columns. */
409  for (col = 0; col < list->cols; col++) {
410  /* Is there any text to show? */
411  if (list->text[row][col] && list->font != NULL) {
412  const char *text_color, *text_color_shadow;
413  SDL_Rect text_rect;
414 
415  extra_width = 0;
416 
417  /* Center it. */
418  if (list->col_centered[col]) {
419  extra_width = list->col_widths[col] / 2 - text_get_width(list->font, list->text[row][col], TEXT_WORD_WRAP) / 2;
420  }
421 
422  text_color = list->focus ? COLOR_WHITE : COLOR_GRAY;
423  text_color_shadow = COLOR_BLACK;
424 
425  if (list->text_color_hook) {
426  list->text_color_hook(list, row, col, &text_color, &text_color_shadow);
427  }
428 
429  /* Add width limit on the string. */
430  text_rect.x = list->x + w + extra_width;
431  text_rect.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list));
432  text_rect.w = list->col_widths[col] + list->col_spacings[col];
433  text_rect.h = LIST_ROW_HEIGHT(list);
434 
435  /* Output the text. */
436  if (text_color_shadow) {
437  text_show_shadow(list->surface, list->font, list->text[row][col], text_rect.x, text_rect.y, text_color, text_color_shadow, TEXT_WORD_WRAP | list->text_flags, &text_rect);
438  } else if (text_color) {
439  text_show(list->surface, list->font, list->text[row][col], text_rect.x, text_rect.y, text_color, TEXT_WORD_WRAP | list->text_flags, &text_rect);
440  }
441  }
442 
443  if (list->post_column_func) {
444  list->post_column_func(list, row, col);
445  }
446 
447  w += list->col_widths[col] + list->col_spacings[col];
448  }
449  }
450 }
451 
458 {
459  uint32_t row, col;
460 
461  if (!list || !list->text) {
462  return;
463  }
464 
465  /* Free the texts. */
466  for (row = 0; row < list->rows; row++) {
467  for (col = 0; col < list->cols; col++) {
468  if (list->text[row][col]) {
469  efree(list->text[row][col]);
470  }
471  }
472 
473  efree(list->text[row]);
474  }
475 
476  efree(list->text);
477  list->text = NULL;
478  list->rows = 0;
479 }
480 
487 {
488  list_clear_rows(list);
489 
490  list->row_selected = 1;
491  list->row_highlighted = 0;
492  list->row_offset = 0;
493 }
494 
502 {
503  if (list->row_selected <= 1) {
504  list->row_selected = 1;
505  } else if (list->row_selected >= list->rows) {
506  list->row_selected = list->rows;
507  }
508 
509  if (list->rows < list->max_rows) {
510  list->row_offset = 0;
511  } else if (list->row_offset >= list->rows - list->max_rows) {
512  list->row_offset = list->rows - list->max_rows;
513  }
514 }
515 
523 {
524  uint32_t col;
525 
526  if (!list) {
527  return;
528  }
529 
530  if (list->data) {
531  efree(list->data);
532  }
533 
534  list_clear(list);
535 
536  efree(list->col_widths);
537  efree(list->col_spacings);
538  efree(list->col_centered);
539 
540  /* Free column names. */
541  for (col = 0; col < list->cols; col++) {
542  if (list->col_names[col]) {
543  efree(list->col_names[col]);
544  }
545  }
546 
547  if (list->font != NULL) {
548  font_free(list->font);
549  }
550 
551  efree(list->col_names);
552  efree(list);
553 }
554 
564 void list_scroll(list_struct *list, int up, int scroll)
565 {
566  /* The actual values are unsigned. Changing them to signed here
567  * makes it easier to check for overflows below. */
568  int32_t row_selected = list->row_selected, row_offset = list->row_offset;
569  int32_t max_rows, rows;
570 
571  /* Number of rows. */
572  rows = list->rows;
573  /* Number of visible rows. */
574  max_rows = list->max_rows;
575 
576  if (up) {
577  /* Scrolling upward. */
578  row_selected -= scroll;
579 
580  /* Adjust row offset if needed. */
581  if (row_offset >= (row_selected - 1)) {
582  row_offset -= scroll;
583  }
584  } else {
585  /* Downward otherwise. */
586  row_selected += scroll;
587 
588  /* Adjust row offset if needed. */
589  if (row_selected >= max_rows + row_offset) {
590  row_offset += scroll;
591  }
592  }
593 
594  /* Make sure row offset is within bounds. */
595  if (row_offset < 0 || rows < max_rows) {
596  row_offset = 0;
597  } else if (row_offset >= rows - max_rows) {
598  row_offset = rows - max_rows;
599  }
600 
601  /* Make sure selected row is within bounds. */
602  if (row_selected < 1) {
603  row_selected = 1;
604  } else if (row_selected >= rows) {
605  row_selected = list->rows;
606  }
607 
608  /* Set the values. */
609  list->row_selected = row_selected;
610  list->row_offset = row_offset;
611 }
612 
622 int list_handle_keyboard(list_struct *list, SDL_Event *event)
623 {
624  if (!list) {
625  return 0;
626  }
627 
628  if (event->type != SDL_KEYDOWN) {
629  return 0;
630  }
631 
632  if (list->key_event_func) {
633  int ret = list->key_event_func(list, event->key.keysym.sym);
634 
635  if (ret != -1) {
636  return ret;
637  }
638  }
639 
640  switch (event->key.keysym.sym) {
641  /* Up arrow. */
642  case SDLK_UP:
643  list_scroll(list, 1, 1);
644  return 1;
645 
646  /* Down arrow. */
647  case SDLK_DOWN:
648  list_scroll(list, 0, 1);
649  return 1;
650 
651  /* Page up. */
652  case SDLK_PAGEUP:
653  list_scroll(list, 1, list->max_rows);
654  return 1;
655 
656  /* Page down. */
657  case SDLK_PAGEDOWN:
658  list_scroll(list, 0, list->max_rows);
659  return 1;
660 
661  /* Esc, let the list creator handle this if they want to. */
662  case SDLK_ESCAPE:
663 
664  if (list->handle_esc_func) {
665  list->handle_esc_func(list);
666  }
667 
668  return 1;
669 
670  /* Enter. */
671  case SDLK_RETURN:
672  case SDLK_KP_ENTER:
673 
674  if (list->handle_enter_func) {
675  list->handle_enter_func(list, event);
676  }
677 
678  return 1;
679 
680  /* Unhandled key. */
681  default:
682  break;
683  }
684 
685  return 0;
686 }
687 
698 int list_handle_mouse(list_struct *list, SDL_Event *event)
699 {
700  uint32_t row, col, old_highlighted, old_selected;
701  int mx, my;
702 
703  if (!list) {
704  return 0;
705  }
706 
707  if (event->type != SDL_MOUSEBUTTONDOWN && event->type != SDL_MOUSEBUTTONUP && event->type != SDL_MOUSEMOTION) {
708  return 0;
709  }
710 
711  mx = event->motion.x - list->px;
712  my = event->motion.y - list->py;
713 
714  if (list->scrollbar_enabled) {
715  list->scrollbar.px = list->px;
716  list->scrollbar.py = list->py;
717 
718  if (scrollbar_event(&list->scrollbar, event)) {
719  return 1;
720  }
721  }
722 
723  if (!LIST_MOUSE_OVER(list, mx, my)) {
724  return 0;
725  }
726 
727  old_highlighted = list->row_highlighted;
728  old_selected = list->row_selected;
729 
730  /* No row is highlighted now. Will be switched back on as needed
731  * below. */
732  list->row_highlighted = 0;
733 
734  if (list_mouse_get_pos(list, event->motion.x, event->motion.y, &row, &col)) {
735  if (list->handle_mouse_row_func) {
736  list->handle_mouse_row_func(list, row, event);
737  }
738 
739  /* Mouse click? */
740  if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT) {
741  /* See if we clicked on this row earlier, and whether this
742  * should be considered a double click. */
743  if (SDL_GetTicks() - list->click_tick < DOUBLE_CLICK_DELAY) {
744  /* Double click, handle it as if enter was used. */
745  if (list->handle_enter_func) {
746  list->handle_enter_func(list, event);
747  list->click_tick = 0;
748  }
749 
750  /* Update selected row (in case enter handling
751  * function did not actually jump to another GUI,
752  * thus removing the need for this list). */
753  list->row_selected = row + 1;
754  } else { /* Normal click. */
755  /* Update selected row and click ticks for above
756  * double click calculation. */
757  list->row_selected = row + 1;
758  list->click_tick = SDL_GetTicks();
759  }
760  } else {
761  /* Not a mouse click, so update highlighted row. */
762  list->row_highlighted = row + 1;
763  }
764  }
765 
766  /* Handle mouse wheel for scrolling. */
767  if (event->type == SDL_MOUSEBUTTONDOWN && (event->button.button == SDL_BUTTON_WHEELUP || event->button.button == SDL_BUTTON_WHEELDOWN)) {
768  list_scroll(list, event->button.button == SDL_BUTTON_WHEELUP, 1);
769  return 1;
770  }
771 
772  if (old_highlighted != list->row_highlighted || old_selected != list->row_selected) {
773  return 1;
774  }
775 
776  return 0;
777 }
778 
779 int list_mouse_get_pos(list_struct *list, int mx, int my, uint32_t *row, uint32_t *col)
780 {
781  uint32_t w;
782 
783  mx -= list->px;
784  my -= list->py;
785 
786  /* See which row the mouse is over. */
787  for (*row = list->row_offset; *row < list->rows; (*row)++) {
788  /* Stop if we reached maximum number of visible rows. */
789  if (LIST_ROW_OFFSET(*row, list) == list->max_rows) {
790  break;
791  }
792 
793  /* Is the mouse over this row? */
794  if ((uint32_t) my >= (LIST_ROWS_START(list) + LIST_ROW_OFFSET(*row, list) * LIST_ROW_HEIGHT(list)) && (uint32_t) my < LIST_ROWS_START(list) + (LIST_ROW_OFFSET(*row, list) + 1) * LIST_ROW_HEIGHT(list)) {
795  w = 0;
796 
797  for (*col = 0; *col < list->cols; (*col)++) {
798  if ((uint32_t) mx >= list->x + list->frame_offset + w && (uint32_t) mx < list->x + list->frame_offset + w + list->col_widths[*col] + list->col_spacings[*col]) {
799  return 1;
800  }
801 
802  w += list->col_widths[*col] + list->col_spacings[*col];
803  }
804  }
805  }
806 
807  return 0;
808 }
809 
819 static int list_compare_alpha(const void *a, const void *b)
820 {
821  return strcmp(((char ***) a)[0][0], ((char ***) b)[0][0]);
822 }
823 
832 void list_sort(list_struct *list, int type)
833 {
834  if (!list->text) {
835  return;
836  }
837 
838  /* Alphabetical sort. */
839  if (type == LIST_SORT_ALPHA) {
840  qsort(list->text, list->rows, sizeof(*list->text), list_compare_alpha);
841  }
842 }
843 
855 int list_set_selected(list_struct *list, const char *str, uint32_t col)
856 {
857  uint32_t row;
858 
859  for (row = 0; row < list->rows; row++) {
860  if (!strcmp(list->text[row][col], str)) {
861  list->row_selected = row + 1;
862  list->row_offset = MIN(list->rows - list->max_rows, row);
863  return 1;
864  }
865  }
866 
867  return 0;
868 }
869 
879 const char *list_get_selected(list_struct *list, uint32_t col)
880 {
881  if (list->text == NULL) {
882  return NULL;
883  }
884 
885  return list->text[list->row_selected - 1][col];
886 }
int spacing
Definition: list.h:66
void(* row_selected_func)(struct list_struct *list, SDL_Rect box)
Definition: list.h:184
list_struct * list_create(uint32_t max_rows, uint32_t cols, int spacing)
Definition: list.c:113
void * data
Definition: list.h:147
#define COLOR_BLACK
Definition: text.h:323
#define TEXT_WORD_WRAP
Definition: text.h:226
font_struct * font
Definition: list.h:135
uint8_t focus
Definition: list.h:126
static void list_row_color(list_struct *list, int row, SDL_Rect box)
Definition: list.c:54
static void list_draw_frame(list_struct *list)
Definition: list.c:40
void list_remove(list_struct *list)
Definition: list.c:522
int x
Definition: list.h:36
void list_clear(list_struct *list)
Definition: list.c:486
void list_set_column(list_struct *list, uint32_t col, int width, int spacing, const char *name, int centered)
Definition: list.c:242
#define LIST_SORT_ALPHA
Definition: list.h:285
uint8_t scrollbar_enabled
Definition: list.h:129
int list_handle_mouse(list_struct *list, SDL_Event *event)
Definition: list.c:698
void text_show(SDL_Surface *surface, font_struct *font, const char *text, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box)
Definition: text.c:1983
void list_add(list_struct *list, uint32_t row, uint32_t col, const char *str)
Definition: list.c:163
uint8_t * col_centered
Definition: list.h:78
void draw_frame(SDL_Surface *surface, int x, int y, int w, int h)
Definition: sprite.c:1185
int16_t frame_offset
Definition: list.h:94
#define LIST_ROWS_START(list)
Definition: list.h:258
int scrollbar_need_redraw(scrollbar_struct *scrollbar)
Definition: scrollbar.c:267
int y
Definition: list.h:39
void(* draw_frame_func)(struct list_struct *list)
Definition: list.h:155
uint32_t row_offset
Definition: list.h:117
uint64_t text_flags
Definition: list.h:141
int px
Definition: list.h:45
void font_free(font_struct *font)
Definition: text.c:262
char *** text
Definition: list.h:85
int py
Definition: list.h:51
SDL_Surface * ScreenSurface
Definition: main.c:47
#define LIST_ROW_HEIGHT(list)
Definition: list.h:256
void list_scroll(list_struct *list, int up, int scroll)
Definition: list.c:564
void(* handle_mouse_row_func)(struct list_struct *list, uint32_t row, SDL_Event *event)
Definition: list.h:252
void scrollbar_show(scrollbar_struct *scrollbar, SDL_Surface *surface, int x, int y)
Definition: scrollbar.c:443
static void list_row_selected(list_struct *list, SDL_Rect box)
Definition: list.c:82
#define LIST_ROW_OFFSET(row, list)
Definition: list.h:267
static void list_row_highlight(list_struct *list, SDL_Rect box)
Definition: list.c:70
void list_remove_row(list_struct *list, uint32_t row)
Definition: list.c:198
uint32_t click_tick
Definition: list.h:123
#define COLOR_GRAY
Definition: text.h:301
void list_clear_rows(list_struct *list)
Definition: list.c:457
uint32_t row_highlighted
Definition: list.h:103
void list_offsets_ensure(list_struct *list)
Definition: list.c:501
int list_need_redraw(list_struct *list)
Definition: list.c:315
int * col_spacings
Definition: list.h:72
#define FONT_INCREF(font)
Definition: text.h:67
void(* row_color_func)(struct list_struct *list, int row, SDL_Rect box)
Definition: list.h:166
void(* text_color_hook)(struct list_struct *list, uint32_t row, uint32_t col, const char **color, const char **color_shadow)
Definition: list.h:228
void text_show_shadow(SDL_Surface *surface, font_struct *font, const char *text, int x, int y, const char *color_notation, const char *color_shadow_notation, uint64_t flags, SDL_Rect *box)
Definition: text.c:2278
uint32_t max_rows
Definition: list.h:57
void scrollbar_create(scrollbar_struct *scrollbar, int w, int h, uint32_t *scroll_offset, uint32_t *num_lines, uint32_t max_lines)
Definition: scrollbar.c:350
void(* row_highlight_func)(struct list_struct *list, SDL_Rect box)
Definition: list.h:175
void(* post_column_func)(struct list_struct *list, uint32_t row, uint32_t col)
Definition: list.h:239
int width
Definition: list.h:54
#define DOUBLE_CLICK_DELAY
Definition: list.h:289
void list_sort(list_struct *list, int type)
Definition: list.c:832
int list_handle_keyboard(list_struct *list, SDL_Event *event)
Definition: list.c:622
SDL_Surface * surface
Definition: list.h:138
uint32_t * col_widths
Definition: list.h:69
char ** col_names
Definition: list.h:75
uint16_t header_height
Definition: list.h:97
void list_set_font(list_struct *list, font_struct *font)
Definition: list.c:284
int text_get_width(font_struct *font, const char *text, uint64_t flags)
Definition: text.c:2328
void list_show(list_struct *list, int x, int y)
Definition: list.c:337
#define LIST_MOUSE_OVER(list, mx, my)
Definition: list.h:278
void(* handle_esc_func)(struct list_struct *list)
Definition: list.h:191
int scrollbar_event(scrollbar_struct *scrollbar, SDL_Event *event)
Definition: scrollbar.c:529
#define LIST_ROWS_HEIGHT(list)
Definition: list.h:262
static int list_compare_alpha(const void *a, const void *b)
Definition: list.c:819
scrollbar_struct scrollbar
Definition: list.h:132
void list_set_parent(list_struct *list, int px, int py)
Definition: list.c:96
uint32_t cols
Definition: list.h:63
void list_scrollbar_enable(list_struct *list)
Definition: list.c:302
int list_set_selected(list_struct *list, const char *str, uint32_t col)
Definition: list.c:855
int(* key_event_func)(struct list_struct *list, SDLKey key)
Definition: list.h:214
uint32_t rows
Definition: list.h:60
void(* handle_enter_func)(struct list_struct *list, SDL_Event *event)
Definition: list.h:201
const char * list_get_selected(list_struct *list, uint32_t col)
Definition: list.c:879
uint32_t row_selected
Definition: list.h:109
#define COLOR_WHITE
Definition: text.h:289