Add mouse support for scroll area

Internal Changelog:
- Refactor scroll area refocus function
    - This only triggers when selection is made
- Add mouse function process in test scene
- Add action for mouse selection
main
En Yi 2024-07-08 19:16:10 +08:00
parent eff3d090df
commit 9b6c364269
4 changed files with 73 additions and 10 deletions

View File

@ -663,6 +663,37 @@ void vert_scrollarea_insert_item(VertScrollArea_t* scroll_area, char* str, unsig
DrawText(str, 0, scroll_area->item_padding + (scroll_area->item_height + scroll_area->item_padding) * item_idx, scroll_area->item_height, BLACK); DrawText(str, 0, scroll_area->item_padding + (scroll_area->item_height + scroll_area->item_padding) * item_idx, scroll_area->item_height, BLACK);
} }
unsigned int vert_scrollarea_set_pos(VertScrollArea_t* scroll_area, Vector2 pos)
{
float x = pos.x - scroll_area->display_area.x;
float y = pos.y - scroll_area->display_area.y;
if (x >= scroll_area->display_area.width || x < 0) return scroll_area->n_items;
if (y >= scroll_area->display_area.height || y < 0) return scroll_area->n_items;
scroll_area->curr_selection = (y - scroll_area->item_padding + (scroll_area->scroll_bounds.y - scroll_area->scroll_pos)) / (scroll_area->item_height + scroll_area->item_padding);
return scroll_area->curr_selection;
}
void vert_scrollarea_refocus(VertScrollArea_t* scroll_area)
{
float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding - (scroll_area->scroll_bounds.y - scroll_area->scroll_pos);
// Auto adjust scroll based on selection
if (selection_y < 0)
{
scroll_area->scroll_pos -= selection_y;
}
else if (selection_y + scroll_area->item_height + scroll_area->item_padding > scroll_area->display_area.height)
{
scroll_area->scroll_pos -= selection_y + scroll_area->item_height + scroll_area->item_padding - scroll_area->display_area.height;
}
}
void vert_scrollarea_render(VertScrollArea_t* scroll_area) 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); BeginScissorMode(scroll_area->comp.bbox.x, scroll_area->comp.bbox.y, scroll_area->comp.bbox.width, scroll_area->comp.bbox.height);
@ -687,16 +718,6 @@ void vert_scrollarea_render(VertScrollArea_t* scroll_area)
Fade(BLUE, 0.7) Fade(BLUE, 0.7)
); );
// Auto adjust scroll based on selection
if (selection_y < 0)
{
scroll_area->scroll_pos -= selection_y;
}
else if (selection_y + scroll_area->item_height + scroll_area->item_padding > scroll_area->display_area.height)
{
scroll_area->scroll_pos -= selection_y + scroll_area->item_height + scroll_area->item_padding - scroll_area->display_area.height;
}
Vector2 draw_pos = {scroll_area->display_area.x, scroll_area->display_area.y}; Vector2 draw_pos = {scroll_area->display_area.x, scroll_area->display_area.y};
draw_rec.height *= -1; draw_rec.height *= -1;
DrawTextureRec( DrawTextureRec(

View File

@ -32,6 +32,8 @@ void init_UI(void);
void vert_scrollarea_init(VertScrollArea_t* scroll_area, Rectangle display_area, Vector2 canvas_dims); 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_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_insert_item(VertScrollArea_t* scroll_area, char* str, unsigned int item_idx);
unsigned int vert_scrollarea_set_pos(VertScrollArea_t* scroll_area, Vector2 pos);
void vert_scrollarea_refocus(VertScrollArea_t* scroll_area);
void vert_scrollarea_render(VertScrollArea_t* scroll_area); void vert_scrollarea_render(VertScrollArea_t* scroll_area);
void vert_scrollarea_free(VertScrollArea_t* scroll_area); void vert_scrollarea_free(VertScrollArea_t* scroll_area);

View File

@ -22,6 +22,8 @@ int main(void)
while(true) while(true)
{ {
Vector2 raw_mouse_pos = GetMousePosition();
scene.scene.mouse_pos = raw_mouse_pos;
// This entire key processing relies on the assumption that a pressed key will // This entire key processing relies on the assumption that a pressed key will
// appear in the polling of raylib // appear in the polling of raylib
@ -52,6 +54,18 @@ int main(void)
do_action(&scene.scene, action, true); do_action(&scene.scene, action, true);
sc_queue_add_last(&key_buffer, button); sc_queue_add_last(&key_buffer, button);
} }
ActionType_t action = sc_map_get_64(&scene.scene.action_map, MOUSE_BUTTON_LEFT);
if (sc_map_found(&scene.scene.action_map))
{
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
{
do_action(&scene.scene, action, true);
}
else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
{
do_action(&scene.scene, action, false);
}
}
float frame_time = GetFrameTime(); float frame_time = GetFrameTime();
float delta_time = fminf(frame_time, DT); float delta_time = fminf(frame_time, DT);

View File

@ -24,6 +24,7 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
if (data->scroll_area.curr_selection > 0) if (data->scroll_area.curr_selection > 0)
{ {
data->scroll_area.curr_selection--; data->scroll_area.curr_selection--;
vert_scrollarea_refocus(&data->scroll_area);
} }
} }
break; break;
@ -33,6 +34,7 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
if (data->scroll_area.curr_selection < data->scroll_area.n_items - 1) if (data->scroll_area.curr_selection < data->scroll_area.n_items - 1)
{ {
data->scroll_area.curr_selection++; data->scroll_area.curr_selection++;
vert_scrollarea_refocus(&data->scroll_area);
} }
} }
break; break;
@ -45,6 +47,29 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre
} }
} }
break; break;
case ACTION_NEXT_SPAWN:
if (!pressed)
{
unsigned int prev_sel = data->scroll_area.curr_selection;
if (vert_scrollarea_set_pos(&data->scroll_area, scene->mouse_pos) != data->scroll_area.n_items)
{
vert_scrollarea_refocus(&data->scroll_area);
}
if (prev_sel == data->scroll_area.curr_selection)
{
if (data->level_pack != NULL && data->scroll_area.curr_selection < data->level_pack->n_levels)
{
// TODO: Need to load the current level
LevelScene_t* level_scene = (LevelScene_t*)change_scene(scene->engine, GAME_SCENE);
level_scene->data.level_pack = data->level_pack;
level_scene->data.current_level = data->scroll_area.curr_selection;
reload_level_tilemap(level_scene);
}
}
}
break;
case ACTION_CONFIRM: case ACTION_CONFIRM:
if (!pressed) if (!pressed)
{ {
@ -107,6 +132,7 @@ void init_level_select_scene(LevelSelectScene_t* scene)
sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN);
sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT); sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT);
sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM); sc_map_put_64(&scene->scene.action_map, KEY_ENTER, ACTION_CONFIRM);
sc_map_put_64(&scene->scene.action_map, MOUSE_LEFT_BUTTON, ACTION_NEXT_SPAWN); // Abuse an unused action
} }
void free_level_select_scene(LevelSelectScene_t* scene) void free_level_select_scene(LevelSelectScene_t* scene)
{ {