summaryrefslogtreecommitdiff
path: root/src/gui/list.cpp
blob: 90f2f491502e66f5e56164159000befaa76727d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "base.h"

const I32 LIST_TITLE_OFFSET = 15;
const I32 LIST_ITEM_HEIGHT = 18;

void gui_list_draw_fn( void* ptr ) {
  GUI_LIST* list = (GUI_LIST*)ptr;

  I32 x = gui_relx( list );
  I32 y = gui_rely( list );

  gui_draw_str( x, y, ALIGN_L, FNT_JPN12, ui_clr.txt, list->name );
  y += LIST_TITLE_OFFSET;

  CLR col = gui_is_fg_window( list )? ui_clr.border : ui_clr.border_inactive;
  gui_draw_frect( x, y, list->w, list->h, col );
  gui_draw_frect( x+1, y+1, list->w-2, list->h-2, ui_clr.bg_sec );

  I32 yoff = 0;
  list->plist->each( fn( GUI_LIST_ENTRY* e ) {
    U8 selected = e->val == *list->pval;
    CLR col = selected? ui_clr.txt : ui_clr.txt_inactive;

    gui_draw_str( x + 4, y + yoff + 6, ALIGN_L, FNT_JPN12, col, e->title );
    yoff += LIST_ITEM_HEIGHT;
  } );
}

void gui_list_input_fn( void* ptr ) {
  GUI_LIST* list = (GUI_LIST*)ptr;

  I32 x = gui_relx( list );
  I32 y = gui_rely( list );
  I32 w = list->w;
  I32 h = list->h;

  U8 m1 = gui_mbutton_down( 0 );
  I32 mx, my;
  gui_cursor_pos( &mx, &my );

  U8 inbounds = mx >= x && mx <= x + w && my >= y && my <= y + h;
  if( !inbounds )
    return;

  I32 diff = my - y;
  I32 idx = diff / LIST_ITEM_HEIGHT - 1;
  if( idx >= list->plist->size ) idx = list->plist->size - 1;
  if( idx < 0 ) idx = 0;

  if( m1 ) {
    if( !list->held ) {
      GUI_LIST_ENTRY* e = &list->plist->data[idx];
      I32 prevval = *list->pval;
      *list->pval = e->val;

      if( list->cb && prevval != *list->pval )
        list->cb( list );
    }
    list->held = 1;
  } else {
    list->held = 0;
  }
}

GUI_LIST* gui_list( I32 x, I32 y, I32 w, I32 h, const char* title, LIST<GUI_LIST_ENTRY>* plist, I32* pval ) {
  if( !gui_check_target() ) return 0;

  GUI_LIST* list = new GUI_LIST;
  list->x = x;
  list->y = y;
  list->w = w;
  list->h = h;

  list->xbound = w;
  list->ybound = h + LIST_TITLE_OFFSET;

  list->cb = 0;
  list->pval = pval;
  list->plist = plist;
  list->draw_fn = gui_list_draw_fn;
  list->input_fn = gui_list_input_fn;
  strcpy( list->name, title );

  list->parent = gui_get_view();

  gui_get_view()->children.push( list );
  return list;
}

GUI_LIST_ENTRY* gui_list_get_selected( GUI_LIST* list ) {
  for( U32 i = 0; i < list->plist->size; ++i ) {
    GUI_LIST_ENTRY* e = &list->plist->data[i];
    if( e->val == *list->pval )
      return e;
  }

  return 0;
}