working camera, inventory, and arrow buttons

This commit is contained in:
frank 2021-11-19 14:14:42 -05:00
parent 16cc5406cf
commit cecf008d5e
5 changed files with 86 additions and 33 deletions

2
lib/sb

@ -1 +1 @@
Subproject commit 660865b2f21b61f145f351514e51b26e3f0b68e9 Subproject commit 86ca3eabec1d46a5a56d004fb5f3abd90304b9a8

View File

@ -75,11 +75,9 @@ public:
/* Return true if the carousel currently points to the location at the end of the container. */ /* Return true if the carousel currently points to the location at the end of the container. */
template<typename Container> template<typename Container>
bool at_end(const Container& container) const bool at_end(const Container& container)
{ {
auto location = container.begin(); return offset >= container.size() - 1;
std::advance(location, offset);
return location == container.end();
} }
}; };

View File

@ -113,3 +113,15 @@ bool Item::at_last()
{ {
return carousel.at_end(item_view.textures()); return carousel.at_end(item_view.textures());
} }
/* Set current texture to the first texture added. */
void Item::to_first()
{
carousel.beginning();
}
/* Set texture to the last texture added. */
void Item::to_last()
{
carousel.end(item_view.textures());
}

View File

@ -63,6 +63,8 @@ public:
Plane& view(); Plane& view();
bool at_first() const; bool at_first() const;
bool at_last(); bool at_last();
void to_first();
void to_last();
}; };

View File

@ -330,16 +330,32 @@ void Pudding::respond(SDL_Event& event)
/* Mouse interface */ /* Mouse interface */
else if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN) else if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN)
{ {
glm::vec2 mouse = event.type == SDL_MOUSEBUTTONDOWN ? glm::vec2{event.button.x, event.button.y} : /* Get the secondary window viewport dimensions in NDC and pixel resolution for sizing the arrow buttons and transforming
* the mouse coordinates. */
Box viewport_ndc = sb::Display::ndc;
/* Drag viewport completely closed to the bottom of the screen */
viewport_ndc.top(viewport_ndc.bottom(), true);
nlohmann::json interface = get_configuration()["interface"];
/* Drag viewport back up the height of the pop-up window */
viewport_ndc.drag_top(interface["pop-up-viewport-height"]);
/* Get the viewport in pixel resolution to size the buttons to be square inside the viewport */
Box viewport_pixel = get_display().ndc_to_pixel(viewport_ndc);
/* Get mouse coordinates in NDC and pixel resolution in both main window and secondary */
glm::vec2 mouse_pixel = event.type == SDL_MOUSEBUTTONDOWN ? glm::vec2{event.button.x, event.button.y} :
glm::vec2{event.motion.x, event.motion.y}; glm::vec2{event.motion.x, event.motion.y};
glm::vec2 ndc { glm::vec2 mouse_ndc {
float(mouse.x) / window_box().width() * 2.0f - 1.0f, (1.0f - float(mouse.y) / window_box().height()) * 2.0f - 1.0f float(mouse_pixel.x) / window_box().width() * 2.0f - 1.0f, (1.0f - float(mouse_pixel.y) / window_box().height()) * 2.0f - 1.0f
}; };
bool over_camera_button = !capture.isOpened() && !item_display_active() && camera_button.collide(ndc), glm::vec2 mouse_viewport_ndc {
over_inventory_button = items.size() > 0 && !item_display_active() && !capture.isOpened() && inventory_button.collide(ndc), mouse_ndc.x, (1.0f - (float(mouse_pixel.y) - float(viewport_pixel.top())) / viewport_pixel.height()) * 2.0f - 1.0f
over_close_area = (capture.isOpened() || item_display_active()) && get_display().ndc_subsection(main_viewport).collide(ndc); };
bool over_camera_button = !capture.isOpened() && !item_display_active() && camera_button.collide(mouse_ndc),
over_inventory_button = items.size() > 0 && !item_display_active() && !capture.isOpened() && inventory_button.collide(mouse_ndc),
over_close_area = (capture.isOpened() || item_display_active()) && get_display().ndc_subsection(main_viewport).collide(mouse_ndc),
over_previous_button = item_display_active() && previous_button.collide(mouse_viewport_ndc),
over_next_button = item_display_active() && next_button.collide(mouse_viewport_ndc);
/* Check for collisions with anything clickable */ /* Check for collisions with anything clickable */
if (over_camera_button || over_inventory_button || over_close_area) if (over_camera_button || over_inventory_button || over_close_area || over_previous_button || over_next_button)
{ {
/* Set cursor to pokey finger */ /* Set cursor to pokey finger */
if (SDL_GetCursor() != poke.get()) if (SDL_GetCursor() != poke.get())
@ -349,30 +365,54 @@ void Pudding::respond(SDL_Event& event)
/* Respond to a click */ /* Respond to a click */
if (event.type == SDL_MOUSEBUTTONDOWN) if (event.type == SDL_MOUSEBUTTONDOWN)
{ {
/* Reset cursor to default arrow */ if (over_camera_button || over_inventory_button || over_close_area)
SDL_SetCursor(SDL_GetDefaultCursor());
if (over_camera_button)
{ {
camera_switch.connect(); /* Reset cursor to default arrow */
SDL_SetCursor(SDL_GetDefaultCursor());
if (over_camera_button)
{
camera_switch.connect();
}
else if (over_inventory_button)
{
show_item = true;
/* Scale buttons according to viewport that is going to open */
next_button.scale(interface["arrow-button-scale"], viewport_pixel.aspect());
previous_button.scale(interface["arrow-button-scale"], viewport_pixel.aspect());
}
else if (over_close_area)
{
camera_switch.disconnect();
show_item = false;
}
} }
else if (over_inventory_button) else
{ {
show_item = true; /* Handle arrow buttons */
Box viewport = sb::Display::ndc; if (over_next_button)
/* Drag viewport completely closed to the bottom of the screen */ {
viewport.top(viewport.bottom(), true); if (current_item().at_last())
nlohmann::json interface = get_configuration()["interface"]; {
/* Drag viewport back up the height of the pop-up window */ item_carousel.next(items);
viewport.drag_top(interface["pop-up-viewport-height"]); current_item().to_first();
/* Get the viewport in pixel resolution to size the buttons to be square inside the viewport */ }
Box pixel_resolution = get_display().ndc_to_pixel(viewport); else
next_button.scale(interface["arrow-button-scale"], pixel_resolution.aspect()); {
previous_button.scale(interface["arrow-button-scale"], pixel_resolution.aspect()); current_item().next_texture();
} }
else if (over_close_area) }
{ else
camera_switch.disconnect(); {
show_item = false; if (current_item().at_first())
{
item_carousel.previous(items);
current_item().to_last();
}
else
{
current_item().previous_texture();
}
}
} }
} }
} }
@ -972,6 +1012,7 @@ void Pudding::update()
viewport.left(window_box(true).left()); viewport.left(window_box(true).left());
glViewport(viewport); glViewport(viewport);
/* bind texture for drawing */ /* bind texture for drawing */
glUniformMatrix4fv(uniform["flat"]["transformation"], 1, GL_FALSE, &camera_view.transformation()[0][0]);
camera_view.current().bind(); camera_view.current().bind();
camera_view.enable(); camera_view.enable();
/* draws rectangle vertices and rectangle texture using UV coords */ /* draws rectangle vertices and rectangle texture using UV coords */