tiny 'arrow' buttons use event loop to allow cancel click

This commit is contained in:
2025-03-15 16:50:17 -05:00
parent 9199502c62
commit b401b3dbc1
3 changed files with 100 additions and 72 deletions

View File

@@ -1612,8 +1612,8 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
if(point_in_area.in(pc_help_button)) { if(point_in_area.in(pc_help_button)) {
rectangle help_button = pc_help_button; rectangle help_button = pc_help_button;
help_button.offset(pc_win_ul); help_button.offset(pc_win_ul);
arrow_button_click(help_button); if(arrow_button_click(help_button, &fps_limiter))
show_dialog_action("help-party"); show_dialog_action("help-party");
} }
for(int i = 0; i < 6; i++) for(int i = 0; i < 6; i++)
for(auto j : pc_buttons[i].keys()) for(auto j : pc_buttons[i].keys())
@@ -1623,27 +1623,27 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
break; break;
rectangle button_rect = pc_buttons[i][j]; rectangle button_rect = pc_buttons[i][j];
button_rect.offset(pc_win_ul); button_rect.offset(pc_win_ul);
arrow_button_click(button_rect); if(arrow_button_click(button_rect, &fps_limiter))
switch(j) { switch(j) {
case PCBTN_NAME: case PCBTN_NAME:
handle_switch_pc(i, need_redraw, need_reprint); handle_switch_pc(i, need_redraw, need_reprint);
break; break;
case PCBTN_HP: case PCBTN_HP:
handle_print_pc_hp(i, need_reprint); handle_print_pc_hp(i, need_reprint);
break; break;
case PCBTN_SP: case PCBTN_SP:
handle_print_pc_sp(i, need_reprint); handle_print_pc_sp(i, need_reprint);
break; break;
case PCBTN_INFO: case PCBTN_INFO:
give_pc_info(i); give_pc_info(i);
// don't call advance_time // don't call advance_time
return false; return false;
case PCBTN_TRADE: case PCBTN_TRADE:
handle_trade_places(i, need_reprint); handle_trade_places(i, need_reprint);
break; break;
case MAX_ePlayerButton: case MAX_ePlayerButton:
break; // Not a button break; // Not a button
} }
} }
put_pc_screen(); put_pc_screen();
put_item_screen(stat_window); put_item_screen(stat_window);
@@ -1664,21 +1664,21 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
if(item_bottom_button_active[i] > 0 && point_in_area.in(item_screen_button_rects[i])) { if(item_bottom_button_active[i] > 0 && point_in_area.in(item_screen_button_rects[i])) {
rectangle button_rect = item_screen_button_rects[i]; rectangle button_rect = item_screen_button_rects[i];
button_rect.offset(item_win_ul); button_rect.offset(item_win_ul);
arrow_button_click(button_rect); if(arrow_button_click(button_rect, &fps_limiter))
switch(i) { switch(i) {
case 6: // special screen case 6: // special screen
set_stat_window(ITEM_WIN_SPECIAL, true); set_stat_window(ITEM_WIN_SPECIAL, true);
break; break;
case 7: case 7:
set_stat_window(ITEM_WIN_QUESTS, true); set_stat_window(ITEM_WIN_QUESTS, true);
break; break;
case 8: // help case 8: // help
show_dialog_action("help-inventory"); show_dialog_action("help-inventory");
break; break;
default: default:
handle_switch_pc_items(i, need_redraw); handle_switch_pc_items(i, need_redraw);
break; break;
} }
} }
if(stat_window <= ITEM_WIN_QUESTS) { if(stat_window <= ITEM_WIN_QUESTS) {
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
@@ -1686,33 +1686,33 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
if(item_area_button_active[i][j] && point_in_area.in(item_buttons[i][j])) { if(item_area_button_active[i][j] && point_in_area.in(item_buttons[i][j])) {
rectangle button_rect = item_buttons[i][j]; rectangle button_rect = item_buttons[i][j];
button_rect.offset(item_win_ul); button_rect.offset(item_win_ul);
arrow_button_click(button_rect); if(arrow_button_click(button_rect, &fps_limiter)){
item_hit = item_sbar->getPosition() + i;
item_hit = item_sbar->getPosition() + i; switch(j) {
switch(j) { case ITEMBTN_NAME: case ITEMBTN_ICON: // equip
case ITEMBTN_NAME: case ITEMBTN_ICON: // equip handle_equip_item(item_hit, need_redraw);
handle_equip_item(item_hit, need_redraw); break;
break; case ITEMBTN_USE:
case ITEMBTN_USE: handle_use_item(item_hit, did_something, need_redraw);
handle_use_item(item_hit, did_something, need_redraw); break;
break; case ITEMBTN_GIVE:
case ITEMBTN_GIVE: handle_give_item(item_hit, did_something, need_redraw);
handle_give_item(item_hit, did_something, need_redraw); break;
break; case ITEMBTN_DROP:
case ITEMBTN_DROP: if(stat_window == ITEM_WIN_SPECIAL) {
if(stat_window == ITEM_WIN_SPECIAL) { use_spec_item(spec_item_array[item_hit], need_redraw);
use_spec_item(spec_item_array[item_hit], need_redraw); } else handle_drop_item(item_hit, need_redraw);
} else handle_drop_item(item_hit, need_redraw); break;
break; case ITEMBTN_INFO:
case ITEMBTN_INFO: show_item_info(item_hit);
show_item_info(item_hit); break;
break; case ITEMBTN_SPEC: // sell? That this code was reached indicates that the item was sellable
case ITEMBTN_SPEC: // sell? That this code was reached indicates that the item was sellable // (Based on item_area_button_active)
// (Based on item_area_button_active) handle_item_shop_action(item_hit);
handle_item_shop_action(item_hit); break;
break; case MAX_eItemButton:
case MAX_eItemButton: break; // Not a button
break; // Not a button }
} }
} }
} }

View File

@@ -482,21 +482,48 @@ void draw_start_button(eStartButton which_position,short which_button) {
win_draw_string(mainPtr(),to_rect,button_labels[which_position],eTextMode::CENTRE,style); win_draw_string(mainPtr(),to_rect,button_labels[which_position],eTextMode::CENTRE,style);
} }
void arrow_button_click(rectangle button_rect) { bool arrow_button_click(rectangle button_rect, cFramerateLimiter* fps_limiter) {
if(recording){ if(recording){
// This action is purely cosmetic, for playing the animation and sound accompanying a click on a button whose real action // In a replay, this action is purely cosmetic, for playing the animation and sound
// is recorded afterward // accompanying a click on a button whose real action is recorded afterward
record_action("arrow_button_click", boost::lexical_cast<std::string>(button_rect)); record_action("arrow_button_click", boost::lexical_cast<std::string>(button_rect));
} }
// Draw depressed:
mainPtr().setActive(); mainPtr().setActive();
clip_rect(mainPtr(), button_rect); clip_rect(mainPtr(), button_rect);
// TODO: Mini-event loop so that the click doesn't happen until releasing the mouse button
refresh_stat_areas(1); refresh_stat_areas(1);
mainPtr().display(); mainPtr().display();
play_sound(37, time_in_ticks(5));
// Mini-event loop so that the click doesn't happen until releasing the mouse button:
bool done = false, clicked = false, depressed = true;
if(replaying) clicked = true;
else{
sf::Event e;
while(!done){
refresh_stat_areas(depressed ? 1 : 0);
while(pollEvent(mainPtr(), e)){
if(e.type == sf::Event::MouseButtonReleased){
done = true;
location clickPos(e.mouseButton.x, e.mouseButton.y);
clickPos = mainPtr().mapPixelToCoords(clickPos);
clicked = button_rect.contains(clickPos);
depressed = false;
break;
} else if(e.type == sf::Event::MouseMoved){
location toPos(e.mouseMove.x, e.mouseMove.y);
toPos = mainPtr().mapPixelToCoords(toPos);
depressed = button_rect.contains(toPos);
}
}
fps_limiter->frame_finished();
}
}
undo_clip(mainPtr()); undo_clip(mainPtr());
play_sound(37, time_in_ticks(5));
refresh_stat_areas(0); refresh_stat_areas(0);
return clicked;
} }

View File

@@ -4,6 +4,7 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include "location.hpp" #include "location.hpp"
#include "tools/framerate_limiter.hpp"
enum { enum {
REFRESH_NONE = 0, REFRESH_NONE = 0,
@@ -33,7 +34,7 @@ void draw_startup(short but_type);
void draw_anim(); void draw_anim();
void place_anim(); void place_anim();
void draw_start_button(eStartButton which_position,short which_button); void draw_start_button(eStartButton which_position,short which_button);
void arrow_button_click(rectangle button_rect); bool arrow_button_click(rectangle button_rect, cFramerateLimiter* fps_limiter = nullptr);
void end_startup(); void end_startup();
void load_main_screen(); void load_main_screen();
void redraw_screen(int refresh); void redraw_screen(int refresh);