Encapsulate scroll area as UI component
parent
6dd185b6cd
commit
98b957a8ff
76
engine/gui.c
76
engine/gui.c
|
@ -623,6 +623,82 @@ float UI_slider(const UIComp_t* comp, const char *textLeft, const char *textRigh
|
||||||
return GuiSliderPro(comp, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH));
|
return GuiSliderPro(comp, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vert_scrollarea_init(VertScrollArea_t* scroll_area, Rectangle display_area, Vector2 canvas_dims)
|
||||||
|
{
|
||||||
|
scroll_area->canvas = LoadRenderTexture(canvas_dims.x, canvas_dims.y);
|
||||||
|
scroll_area->scroll_pos = canvas_dims.y - display_area.height;
|
||||||
|
scroll_area->scroll_bounds = (Vector2){
|
||||||
|
0, scroll_area->scroll_pos
|
||||||
|
};
|
||||||
|
|
||||||
|
vert_scrollarea_set_item_dims(scroll_area, 12, 3);
|
||||||
|
scroll_area->curr_selection = 0;
|
||||||
|
|
||||||
|
scroll_area->display_area = display_area;
|
||||||
|
scroll_area->scroll_bar.alpha = 1;
|
||||||
|
scroll_area->scroll_bar.bbox = (Rectangle){
|
||||||
|
display_area.width + display_area.x, display_area.y,
|
||||||
|
0.1f * display_area.width, display_area.height,
|
||||||
|
};
|
||||||
|
scroll_area->scroll_bar.state = STATE_NORMAL;
|
||||||
|
|
||||||
|
scroll_area->comp.alpha = 1;
|
||||||
|
scroll_area->comp.bbox = display_area;
|
||||||
|
scroll_area->comp.bbox.width *= 1.1f;
|
||||||
|
scroll_area->scroll_bar.state = STATE_NORMAL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void vert_scrollarea_set_item_dims(VertScrollArea_t* scroll_area, unsigned int item_height, unsigned int item_padding)
|
||||||
|
{
|
||||||
|
scroll_area->item_height = item_height;
|
||||||
|
scroll_area->item_padding = item_padding;
|
||||||
|
scroll_area->n_items = (scroll_area->canvas.texture.height - scroll_area->item_padding) / (scroll_area->item_height + scroll_area->item_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vert_scrollarea_insert_item(VertScrollArea_t* scroll_area, char* str, unsigned int item_idx)
|
||||||
|
{
|
||||||
|
if (item_idx >= scroll_area->n_items) return;
|
||||||
|
|
||||||
|
DrawText(str, 0, scroll_area->item_padding + (scroll_area->item_height + scroll_area->item_padding) * item_idx, scroll_area->item_height, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vert_scrollarea_render(VertScrollArea_t* scroll_area)
|
||||||
|
{
|
||||||
|
BeginScissorMode(scroll_area->comp.bbox.x, scroll_area->comp.bbox.y, scroll_area->comp.bbox.width, scroll_area->comp.bbox.height);
|
||||||
|
UI_vert_slider(&scroll_area->scroll_bar,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&scroll_area->scroll_pos,
|
||||||
|
scroll_area->scroll_bounds.x,
|
||||||
|
scroll_area->scroll_bounds.y
|
||||||
|
);
|
||||||
|
Rectangle draw_rec = (Rectangle){
|
||||||
|
0, scroll_area->scroll_pos,
|
||||||
|
scroll_area->display_area.width,
|
||||||
|
scroll_area->display_area.height
|
||||||
|
};
|
||||||
|
float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding;
|
||||||
|
DrawRectangle(
|
||||||
|
scroll_area->display_area.x, scroll_area->display_area.y + selection_y - (scroll_area->scroll_bounds.y - scroll_area->scroll_pos),
|
||||||
|
scroll_area->canvas.texture.width, scroll_area->item_height,
|
||||||
|
Fade(BLUE, 0.7)
|
||||||
|
);
|
||||||
|
Vector2 draw_pos = {scroll_area->display_area.x, scroll_area->display_area.y};
|
||||||
|
draw_rec.height *= -1;
|
||||||
|
DrawTextureRec(
|
||||||
|
scroll_area->canvas.texture,
|
||||||
|
draw_rec,
|
||||||
|
draw_pos,
|
||||||
|
WHITE
|
||||||
|
);
|
||||||
|
EndScissorMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vert_scrollarea_free(VertScrollArea_t* scroll_area)
|
||||||
|
{
|
||||||
|
UnloadRenderTexture(scroll_area->canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_UI(void)
|
void init_UI(void)
|
||||||
|
|
30
engine/gui.h
30
engine/gui.h
|
@ -3,6 +3,7 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raygui.h"
|
#include "raygui.h"
|
||||||
|
|
||||||
|
// Generic Component
|
||||||
typedef struct UIComp {
|
typedef struct UIComp {
|
||||||
Rectangle bbox;
|
Rectangle bbox;
|
||||||
GuiState state;
|
GuiState state;
|
||||||
|
@ -10,7 +11,36 @@ typedef struct UIComp {
|
||||||
bool pressed;
|
bool pressed;
|
||||||
} UIComp_t;
|
} UIComp_t;
|
||||||
|
|
||||||
|
typedef struct VertScrollArea {
|
||||||
|
UIComp_t comp; // Display area + scrollbar
|
||||||
|
Rectangle display_area; // Display dimension
|
||||||
|
|
||||||
|
RenderTexture2D canvas; // Complete canvas
|
||||||
|
|
||||||
|
unsigned int n_items;
|
||||||
|
unsigned int curr_selection;
|
||||||
|
unsigned int item_height;
|
||||||
|
unsigned int item_padding;
|
||||||
|
|
||||||
|
float scroll_pos;
|
||||||
|
Vector2 scroll_bounds;
|
||||||
|
UIComp_t scroll_bar;
|
||||||
|
|
||||||
|
} VertScrollArea_t;
|
||||||
|
|
||||||
void init_UI(void);
|
void init_UI(void);
|
||||||
|
void vert_scrollarea_init(VertScrollArea_t* scroll_area, Rectangle display_area, Vector2 canvas_dims);
|
||||||
|
void vert_scrollarea_set_item_dims(VertScrollArea_t* scroll_area, unsigned int item_height, unsigned int item_padding);
|
||||||
|
void vert_scrollarea_insert_item(VertScrollArea_t* scroll_area, char* str, unsigned int item_idx);
|
||||||
|
void vert_scrollarea_render(VertScrollArea_t* scroll_area);
|
||||||
|
void vert_scrollarea_free(VertScrollArea_t* scroll_area);
|
||||||
|
|
||||||
|
static inline void ScrollAreaRenderBegin(VertScrollArea_t* scroll)
|
||||||
|
{
|
||||||
|
BeginTextureMode(scroll->canvas);
|
||||||
|
}
|
||||||
|
#define ScrollAreaRenderEnd() EndTextureMode()
|
||||||
|
|
||||||
void UI_button(const UIComp_t* bbox, const char* text);
|
void UI_button(const UIComp_t* bbox, const char* text);
|
||||||
float UI_slider(const UIComp_t* comp, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue);
|
float UI_slider(const UIComp_t* comp, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue);
|
||||||
float UI_vert_slider(const UIComp_t* comp, const char *textTop, const char *textBottom, float* value, float minValue, float maxValue);
|
float UI_vert_slider(const UIComp_t* comp, const char *textTop, const char *textBottom, float* value, float minValue, float maxValue);
|
||||||
|
|
|
@ -13,35 +13,9 @@
|
||||||
static void level_select_render_func(Scene_t* scene)
|
static void level_select_render_func(Scene_t* scene)
|
||||||
{
|
{
|
||||||
LevelSelectSceneData_t* data = &(CONTAINER_OF(scene, LevelSelectScene_t, scene)->data);
|
LevelSelectSceneData_t* data = &(CONTAINER_OF(scene, LevelSelectScene_t, scene)->data);
|
||||||
UIComp_t test_comp = {
|
|
||||||
.bbox = {data->level_display.texture.width + 50, 50, 25,
|
|
||||||
scene->layers.render_layers[0].render_area.height - 50
|
|
||||||
},
|
|
||||||
.state = STATE_NORMAL,
|
|
||||||
.alpha = 1.0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
BeginTextureMode(scene->layers.render_layers[0].layer_tex);
|
BeginTextureMode(scene->layers.render_layers[0].layer_tex);
|
||||||
ClearBackground(BLANK);
|
ClearBackground(BLANK);
|
||||||
UI_vert_slider(&test_comp,
|
vert_scrollarea_render(&data->scroll_area);
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&data->scroll,
|
|
||||||
0, HIDDEN_AREA_HEIGHT
|
|
||||||
);
|
|
||||||
Rectangle draw_rec = (Rectangle){
|
|
||||||
0, data->scroll,
|
|
||||||
data->level_display.texture.width,
|
|
||||||
scene->layers.render_layers[0].render_area.height
|
|
||||||
};
|
|
||||||
Vector2 draw_pos = {50, 50};
|
|
||||||
draw_rec.height *= -1;
|
|
||||||
DrawTextureRec(
|
|
||||||
data->level_display.texture,
|
|
||||||
draw_rec,
|
|
||||||
draw_pos,
|
|
||||||
WHITE
|
|
||||||
);
|
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,15 +27,15 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
|
||||||
case ACTION_UP:
|
case ACTION_UP:
|
||||||
if (pressed)
|
if (pressed)
|
||||||
{
|
{
|
||||||
data->scroll += 3;
|
data->scroll_area.scroll_pos += 3;
|
||||||
data->scroll = Clamp(data->scroll, 0, 400);
|
data->scroll_area.scroll_pos = Clamp(data->scroll_area.scroll_pos,data->scroll_area.scroll_bounds.x, data->scroll_area.scroll_bounds.y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_DOWN:
|
case ACTION_DOWN:
|
||||||
if (pressed)
|
if (pressed)
|
||||||
{
|
{
|
||||||
data->scroll -= 3;
|
data->scroll_area.scroll_pos -= 3;
|
||||||
data->scroll = Clamp(data->scroll, 0, 400);
|
data->scroll_area.scroll_pos = Clamp(data->scroll_area.scroll_pos,data->scroll_area.scroll_bounds.x, data->scroll_area.scroll_bounds.y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_EXIT:
|
case ACTION_EXIT:
|
||||||
|
@ -70,6 +44,14 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
|
||||||
change_scene(scene->engine, MAIN_MENU_SCENE);
|
change_scene(scene->engine, MAIN_MENU_SCENE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACTION_CONFIRM:
|
||||||
|
if (data->level_pack != NULL && data->scroll_area.curr_selection < data->level_pack->n_levels)
|
||||||
|
{
|
||||||
|
// TODO: Need to load the current level
|
||||||
|
change_scene(scene->engine, LEVEL_SELECT_SCENE);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,32 +64,31 @@ void init_level_select_scene(LevelSelectScene_t* scene)
|
||||||
&scene->scene, 400, DISPLAY_AREA_HEIGHT,
|
&scene->scene, 400, DISPLAY_AREA_HEIGHT,
|
||||||
(Rectangle){0, 0, 400, DISPLAY_AREA_HEIGHT}
|
(Rectangle){0, 0, 400, DISPLAY_AREA_HEIGHT}
|
||||||
);
|
);
|
||||||
scene->data.level_display = LoadRenderTexture(200, SCROLL_TOTAL_HEIGHT);
|
vert_scrollarea_init(&scene->data.scroll_area, (Rectangle){50, 50, 150, DISPLAY_AREA_HEIGHT - 50}, (Vector2){150, SCROLL_TOTAL_HEIGHT});
|
||||||
scene->data.scroll = scene->data.level_display.texture.height - DISPLAY_AREA_HEIGHT;
|
vert_scrollarea_set_item_dims(&scene->data.scroll_area, FONT_SIZE, TEXT_PADDING);
|
||||||
const unsigned int n_elems = SCROLL_TOTAL_HEIGHT / TEXT_HEIGHT;
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
BeginTextureMode(scene->data.level_display);
|
ScrollAreaRenderBegin(&scene->data.scroll_area);
|
||||||
ClearBackground(GRAY);
|
ClearBackground(BLANK);
|
||||||
if (scene->data.level_pack != NULL)
|
if (scene->data.level_pack != NULL)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < scene->data.level_pack->n_levels; ++i)
|
for (unsigned int i = 0; i < scene->data.level_pack->n_levels; ++i)
|
||||||
{
|
{
|
||||||
DrawText(scene->data.level_pack->levels[i].level_name, 0, TEXT_HEIGHT * i, FONT_SIZE, BLACK);
|
vert_scrollarea_insert_item(&scene->data.scroll_area, scene->data.level_pack->levels[i].level_name, i);
|
||||||
}
|
}
|
||||||
for (unsigned int i = scene->data.level_pack->n_levels; i < n_elems; ++i)
|
for (unsigned int i = scene->data.level_pack->n_levels; i < scene->data.scroll_area.n_items; ++i)
|
||||||
{
|
{
|
||||||
DrawText("---", 0, TEXT_HEIGHT * i, FONT_SIZE, BLACK);
|
vert_scrollarea_insert_item(&scene->data.scroll_area, "---", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < n_elems; ++i)
|
for (unsigned int i = 0; i < scene->data.scroll_area.n_items; ++i)
|
||||||
{
|
{
|
||||||
sprintf(buf, "Level %u", i);
|
sprintf(buf, "Level %u", i);
|
||||||
DrawText(buf, 0, TEXT_HEIGHT * i, FONT_SIZE, BLACK);
|
vert_scrollarea_insert_item(&scene->data.scroll_area, buf, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndTextureMode();
|
ScrollAreaRenderEnd();
|
||||||
|
|
||||||
sc_array_add(&scene->scene.systems, &level_select_render_func);
|
sc_array_add(&scene->scene.systems, &level_select_render_func);
|
||||||
sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP);
|
sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP);
|
||||||
|
@ -116,5 +97,7 @@ void init_level_select_scene(LevelSelectScene_t* scene)
|
||||||
}
|
}
|
||||||
void free_level_select_scene(LevelSelectScene_t* scene)
|
void free_level_select_scene(LevelSelectScene_t* scene)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
vert_scrollarea_free(&scene->data.scroll_area);
|
||||||
free_scene(&scene->scene);
|
free_scene(&scene->scene);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,7 @@ typedef struct MenuScene {
|
||||||
} MenuScene_t;
|
} MenuScene_t;
|
||||||
|
|
||||||
typedef struct LevelSelectSceneData {
|
typedef struct LevelSelectSceneData {
|
||||||
RenderTexture2D level_display;
|
VertScrollArea_t scroll_area;
|
||||||
float scroll;
|
|
||||||
LevelPack_t* level_pack;
|
LevelPack_t* level_pack;
|
||||||
} LevelSelectSceneData_t;
|
} LevelSelectSceneData_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue