summaryrefslogtreecommitdiff
path: root/src/editor/editor_infobox.cpp
blob: 931d9eabbd7fb0560cd1d4613d0b904f8611a520 (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include "editor_gui_internal.h"

#include "../game.h"
#include "../render/gl_2d.h"

constexpr I32 EDITOR_ASSETS_ROW_H = 28;
constexpr I32 EDITOR_ASSETS_THUMB = 20;
constexpr I32 EDITOR_ASSETS_INNER_PAD_X = 8;
constexpr I32 EDITOR_ASSETS_INNER_PAD_Y = 6;
constexpr I32 EDITOR_ASSETS_SCROLLBAR_W = 7;
constexpr I32 EDITOR_ASSETS_SCROLLBAR_GAP = 4;
constexpr I32 EDITOR_ASSETS_SCROLL_STEP = 20;

struct EDITOR_ASSETS_LAYOUT {
  I32 inner_x{};
  I32 inner_y{};
  I32 inner_w{};
  I32 list_h{};
  I32 row_x{};
  I32 row_w{};
  I32 count{};
  I32 content_h{};
  I32 max_scroll{};
  U8 show_scroll{};
  I32 track_x{};
  I32 track_y{};
  I32 track_h{};
};

static EDITOR_ASSETS_LAYOUT editor_assets_layout( GUI_EDITOR_INFOBOX* box, I32 panel_x, I32 panel_y, I32 prop_count ) {
  EDITOR_ASSETS_LAYOUT l{};
  l.inner_x = panel_x + EDITOR_ASSETS_INNER_PAD_X;
  l.inner_y = panel_y + EDITOR_ASSETS_INNER_PAD_Y;
  l.inner_w = max( 1, box->w - ( EDITOR_ASSETS_INNER_PAD_X * 2 ) );
  l.list_h = max( 1, box->h - ( EDITOR_ASSETS_INNER_PAD_Y * 2 ) );
  l.count = prop_count + 1;
  l.content_h = l.count * EDITOR_ASSETS_ROW_H;
  l.max_scroll = max( 0, l.content_h - l.list_h );
  l.show_scroll = l.content_h > l.list_h;
  l.row_x = l.inner_x + 1;
  l.row_w = l.inner_w - 2;
  if( l.show_scroll )
    l.row_w -= EDITOR_ASSETS_SCROLLBAR_W + EDITOR_ASSETS_SCROLLBAR_GAP;
  l.row_w = max( 1, l.row_w );
  l.track_x = l.inner_x + l.inner_w - EDITOR_ASSETS_SCROLLBAR_W - 1 - ( EDITOR_ASSETS_SCROLLBAR_GAP / 2 );
  l.track_y = l.inner_y;
  l.track_h = l.list_h - 2;
  return l;
}

static void editor_assets_clamp_scroll( const EDITOR_ASSETS_LAYOUT& l ) {
  editor->gui.assets_scroll = min( max( 0, editor->gui.assets_scroll ), l.max_scroll );
}

static void gui_editor_infobox_draw_assets( GUI_EDITOR_INFOBOX* box, I32 panel_x, I32 panel_y ) {
  if( !editor->map )
    return;

  WORLD_MAP* map = editor->map;
  EDITOR_ASSETS_LAYOUT l = editor_assets_layout( box, panel_x, panel_y, (I32)map->props.size );
  editor_assets_clamp_scroll( l );
  I32 yoff = -editor->gui.assets_scroll;

  for( I32 idx = 0; idx < l.count; ++idx ) {
    I32 row_y = l.inner_y + idx * EDITOR_ASSETS_ROW_H + yoff;
    if( row_y + EDITOR_ASSETS_ROW_H - 2 <= l.inner_y || row_y >= l.inner_y + l.list_h )
      continue;

    U8 map_entry = idx == 0;
    SURF_PROPS* p = map_entry ? 0 : &map->props[idx - 1];
    U8 selected = 0;
    if( editor->gui.props ) {
      if( map_entry ) {
        selected = editor->gui.props->seltype == EDITOR_SELECT_ORIGIN
                && editor->gui.props->curselect == editor->map;
      } else {
        selected = editor->gui.props->seltype == EDITOR_SELECT_SURFPROPS
                && editor->gui.props->curselect == p;
      }
    }

    CLR rowbg = idx % 2 ? ui_clr.bg : ui_clr.bg_alt;
    if( selected )
      rowbg = CLR::blend( ui_clr.border, ui_clr.bg, 0.70f );

    gui_draw_frect( l.row_x, row_y, l.row_w, EDITOR_ASSETS_ROW_H - 2, rowbg );

    I32 tx = l.row_x + 3;
    I32 ty = row_y + 3;
    gui_draw_frect( tx, ty, EDITOR_ASSETS_THUMB, EDITOR_ASSETS_THUMB, ui_clr.border );
    if( map_entry ) {
      gui_draw_frect( tx + 1, ty + 1, EDITOR_ASSETS_THUMB - 2, EDITOR_ASSETS_THUMB - 2, ui_clr.bg_alt );
      gui_draw_str( tx + EDITOR_ASSETS_THUMB / 2, ty + 4, ALIGN_C, FNT_JPN12, ui_clr.txt, "m" );
    } else if( p->tex ) {
      gl_2d_textured_frect( _gui.gl2d_font, { (F32)(tx + 1), (F32)(ty + 1) }, { (F32)(EDITOR_ASSETS_THUMB - 2), (F32)(EDITOR_ASSETS_THUMB - 2) }, p->tex );
    } else {
      gui_draw_frect( tx + 1, ty + 1, EDITOR_ASSETS_THUMB - 2, EDITOR_ASSETS_THUMB - 2, p->clr );
    }

    I32 text_x = tx + EDITOR_ASSETS_THUMB + 8;
    CLR txt = ui_clr.txt;
    if( map_entry ) {
      gui_draw_str( text_x, row_y + 7, ALIGN_L, FNT_JPN12, txt, "[map] -> %s", map->name );
    } else if( p->tex ) {
      gui_draw_str( text_x, row_y + 7, ALIGN_L, FNT_JPN12, txt, "[%d] -> %s", idx - 1, p->tex->name );
    } else {
      gui_draw_str( text_x, row_y + 7, ALIGN_L, FNT_JPN12, txt, "[%d] -> %.2f, %.2f, %.2f", idx - 1, p->clr.r, p->clr.g, p->clr.b );
    }
  }

  if( !l.show_scroll )
    return;

  gui_draw_frect( l.track_x, l.track_y, EDITOR_ASSETS_SCROLLBAR_W, l.track_h, ui_clr.bg_alt );
  gui_draw_rect( l.track_x, l.track_y, EDITOR_ASSETS_SCROLLBAR_W, l.track_h, ui_clr.border );

  I32 thumb_h = max( 18, ( l.track_h * l.list_h ) / max( 1, l.content_h ) );
  thumb_h = min( thumb_h, l.track_h );
  I32 travel = max( 1, l.track_h - thumb_h );
  I32 thumb_y = l.track_y + ( travel * editor->gui.assets_scroll ) / max( 1, l.max_scroll );
  gui_draw_frect( l.track_x, thumb_y + 1, EDITOR_ASSETS_SCROLLBAR_W, max( 1, thumb_h - 1 ), ui_clr.txt );
}

static void gui_editor_infobox_draw_fn( void* ptr ) {
  GUI_EDITOR_INFOBOX* box = (GUI_EDITOR_INFOBOX*)ptr;
  I32 x = gui_relx( box );
  I32 y = gui_rely( box );
  I32 w = box->w;
  I32 h = box->h;

  if( box->type == EDITOR_INFOBOX_STATUS ) {
    CLR col = gui_is_fg_window( box ) ? ui_clr.border : ui_clr.border_inactive;
    gui_draw_frect( x, y, w, h, col );
    gui_draw_frect( x + 1, y + 1, w - 2, h - 2, ui_clr.bg_sec );
    gui_draw_str(
      x + 6,
      y + 4,
      ALIGN_L,
      FNT_JPN12,
      ui_clr.txt,
      "selected tool: %s. click in viewport to create/edit.",
      editor_tool_name()
    );

    if( editor->game && editor->game->gl ) {
      GL_DATA* gl = editor->game->gl;
      gui_draw_str(
        x + w - 6,
        y + 4,
        ALIGN_R,
        FNT_JPN12,
        ui_clr.txt,
        "fps: %.0f (%.2f ms) %dx%d",
        gl->fps,
        gl->frametime * 1000.f,
        gl->canvas_size[0],
        gl->canvas_size[1]
      );
    }
    return;
  }

  gui_draw_str( x, y, ALIGN_L, FNT_JPN12, ui_clr.txt, "assets" );
  y += EDITOR_LAYOUT_TITLE_OFFSET;

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

  gui_draw_push_clip( x + 2, y + 2, w - 4, h - 4 );
  gui_editor_infobox_draw_assets( box, x, y );
  gui_draw_pop_clip();
}

static void gui_editor_infobox_input_fn( void* ptr ) {
  GUI_EDITOR_INFOBOX* box = (GUI_EDITOR_INFOBOX*)ptr;
  static U8 assets_click_held = 0;
  if( box->type == EDITOR_INFOBOX_ASSETS ) {
    I32 x = gui_relx( box );
    I32 y = gui_rely( box ) + EDITOR_LAYOUT_TITLE_OFFSET;
    I32 w = box->w;
    I32 h = box->h;
    I32 prop_count = editor->map ? (I32)editor->map->props.size : 0;
    EDITOR_ASSETS_LAYOUT l = editor_assets_layout( box, x, y, prop_count );
    editor_assets_clamp_scroll( l );
    I32 mx, my;
    gui_cursor_pos( &mx, &my );
    U8 inbounds = mx >= x && mx <= x + w && my >= y && my <= y + h;
    if( inbounds ) {
      U8 scroll = gui_mbutton_down( GUI_MBTNSCROLL );
      if( scroll ) {
        gui_capture_scroll();
        if( scroll == 1 ) editor->gui.assets_scroll -= EDITOR_ASSETS_SCROLL_STEP;
        else if( scroll == (U8)-1 ) editor->gui.assets_scroll += EDITOR_ASSETS_SCROLL_STEP;
        editor_assets_clamp_scroll( l );
      }

      U8 m1 = gui_mbutton_down( GUI_MBTNLEFT );
      if( m1 && !assets_click_held && editor->map ) {
        if( mx >= l.row_x && mx < l.row_x + l.row_w ) {
          I32 idx = ( my - l.inner_y + editor->gui.assets_scroll ) / EDITOR_ASSETS_ROW_H;
          if( idx >= 0 && idx < l.count && editor->gui.props ) {
            if( idx == 0 ) gui_editor_propview_select( editor->gui.props, editor->map, EDITOR_SELECT_ORIGIN );
            else gui_editor_propview_select( editor->gui.props, &editor->map->props[idx - 1], EDITOR_SELECT_SURFPROPS );
          }
        }
      }
      assets_click_held = m1;
    }

    if( !gui_mbutton_down( GUI_MBTNLEFT ) )
      assets_click_held = 0;
  }

  gui_base_input_fn( box );
}

GUI_EDITOR_INFOBOX* gui_editor_infobox( I32 x, I32 y, I32 w, I32 h, U8 type, const char* name ) {
  if( !gui_check_target() )
    return 0;

  GUI_EDITOR_INFOBOX* box = new GUI_EDITOR_INFOBOX;
  box->x = x;
  box->y = y;
  box->w = w;
  box->h = h;
  box->xbound = w;
  box->ybound = h + ( type == EDITOR_INFOBOX_STATUS ? 0 : EDITOR_LAYOUT_TITLE_OFFSET );
  box->draw_fn = gui_editor_infobox_draw_fn;
  box->input_fn = gui_editor_infobox_input_fn;
  box->type = type;
  strcpy( box->name, name );

  GUI_VIEW* parent = gui_get_view();
  box->parent = parent;
  parent->children.push( box );
  return box;
}