Skip to content

Commit 176bbaa

Browse files
author
s.kushnirenko
committed
ui: redesing button handle system, that avoid draw/handle in different functions
1 parent ca57faf commit 176bbaa

File tree

5 files changed

+91
-41
lines changed

5 files changed

+91
-41
lines changed

src/graphics/elements/generic_button.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "generic_button.h"
22

3-
static int get_button(const mouse* m, int x, int y, generic_button* buttons, int num_buttons) {
3+
#include "input/mouse.h"
4+
5+
static int get_button(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons) {
46
for (int i = 0; i < num_buttons; i++) {
57
if (x + buttons[i].x <= m->x && x + buttons[i].x + buttons[i].width > m->x && y + buttons[i].y <= m->y
68
&& y + buttons[i].y + buttons[i].height > m->y) {
@@ -10,7 +12,7 @@ static int get_button(const mouse* m, int x, int y, generic_button* buttons, int
1012
return 0;
1113
}
1214

13-
static int get_button_min(const mouse* m, int x, int y, generic_button* buttons, int num_buttons, int minimum_button) {
15+
static int get_button_min(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons, int minimum_button) {
1416
for (int i = minimum_button; i < num_buttons; i++) {
1517
if (x + buttons[i].x <= m->x && x + buttons[i].x + buttons[i].width > m->x && y + buttons[i].y <= m->y
1618
&& y + buttons[i].y + buttons[i].height > m->y) {
@@ -20,7 +22,7 @@ static int get_button_min(const mouse* m, int x, int y, generic_button* buttons,
2022
return 0;
2123
}
2224

23-
int generic_buttons_handle_mouse(const mouse* m, int x, int y, generic_button* buttons, int num_buttons, int* focus_button_id) {
25+
int generic_buttons_handle_mouse(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons, int* focus_button_id) {
2426
int button_id = get_button(m, x, y, buttons, num_buttons);
2527
if (focus_button_id) {
2628
*focus_button_id = button_id;
@@ -30,9 +32,12 @@ int generic_buttons_handle_mouse(const mouse* m, int x, int y, generic_button* b
3032
return 0;
3133
}
3234

33-
generic_button* button = &buttons[button_id - 1];
35+
const generic_button* button = &buttons[button_id - 1];
3436
if (m->left.went_up) {
3537
button->left_click_handler(button->parameter1, button->parameter2);
38+
if (button->onclick) {
39+
button->onclick(button->parameter1, button->parameter2);
40+
}
3641
} else if (m->right.went_up) {
3742
button->right_click_handler(button->parameter1, button->parameter2);
3843
} else {
@@ -42,15 +47,15 @@ int generic_buttons_handle_mouse(const mouse* m, int x, int y, generic_button* b
4247
return button_id;
4348
}
4449

45-
int generic_buttons_min_handle_mouse(const mouse* m, int x, int y, generic_button* buttons, int num_buttons, int* focus_button_id, int minimum_button) {
50+
int generic_buttons_min_handle_mouse(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons, int* focus_button_id, int minimum_button) {
4651
int button_id = get_button_min(m, x, y, buttons, num_buttons, minimum_button);
4752
if (focus_button_id)
4853
*focus_button_id = button_id;
4954

5055
if (!button_id)
5156
return 0;
5257

53-
generic_button* button = &buttons[button_id - 1];
58+
const generic_button* button = &buttons[button_id - 1];
5459
if (m->left.went_up)
5560
button->left_click_handler(button->parameter1, button->parameter2);
5661

@@ -61,3 +66,10 @@ int generic_buttons_min_handle_mouse(const mouse* m, int x, int y, generic_butto
6166

6267
return button_id;
6368
}
69+
70+
bool is_button_hover(generic_button &button, vec2i context) {
71+
const mouse *m = mouse_get();
72+
vec2i bpos = context + vec2i{button.x, button.y};
73+
return ( bpos.x <= m->x && bpos.x + button.width > m->x
74+
&& bpos.y <= m->y && bpos.y + button.height > m->y);
75+
}

src/graphics/elements/generic_button.h

+18-8
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,32 @@
44
#include "input/mouse.h"
55

66
#include <vector>
7+
#include <functional>
78

89
struct generic_button {
9-
short x;
10-
short y;
11-
short width;
12-
short height;
10+
int x;
11+
int y;
12+
int width;
13+
int height;
1314
void (*left_click_handler)(int param1, int param2);
1415
void (*right_click_handler)(int param1, int param2);
1516
int parameter1;
1617
int parameter2;
18+
19+
std::function<void(int,int)> onclick;
1720
};
1821

19-
int generic_buttons_handle_mouse(const mouse* m, int x, int y, generic_button* buttons, int num_buttons, int* focus_button_id);
20-
int generic_buttons_min_handle_mouse(const mouse* m, int x, int y, generic_button* buttons, int num_buttons, int* focus_button_id, int minimum_button);
22+
int generic_buttons_handle_mouse(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons, int* focus_button_id);
23+
int generic_buttons_min_handle_mouse(const mouse* m, int x, int y, const generic_button* buttons, int num_buttons, int* focus_button_id, int minimum_button);
24+
25+
bool is_button_hover(generic_button &button, vec2i context);
26+
27+
template<class T, uint32_t N>
28+
inline int generic_buttons_handle_mouse(const mouse *m, vec2i pos, const T (&buttons)[N], int &focus_button_id) {
29+
return generic_buttons_handle_mouse(m, pos.x, pos.y, buttons, N, &focus_button_id);
30+
}
2131

2232
template<class T>
23-
inline int generic_buttons_handle_mouse(const mouse *m, vec2i pos, T &buttons, int &focus_button_id) {
24-
return generic_buttons_handle_mouse(m, pos.x, pos.y, std::begin(buttons), (int)std::size(buttons), &focus_button_id);
33+
inline int generic_buttons_handle_mouse(const mouse *m, vec2i pos, const T &buttons, int &focus_button_id) {
34+
return generic_buttons_handle_mouse(m, pos.x, pos.y, &buttons.front(), buttons.size(), &focus_button_id);
2535
}

src/input/mouse.cpp

+26-6
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ enum { SYSTEM_NONE = 0, SYSTEM_UP = 1, SYSTEM_DOWN = 2, SYSTEM_DOUBLE_CLICK = 4
77

88
#define DOUBLE_CLICK_TIME 500
99

10-
static mouse data;
10+
mouse g_mouse;
1111
static mouse dialog;
1212
static time_millis last_click;
1313

14-
const mouse* mouse_get(void) {
15-
return &data;
16-
}
14+
const mouse* mouse_get() { return &g_mouse; }
1715

1816
static void clear_mouse_button(mouse_button* button) {
1917
button->is_down = 0;
@@ -24,6 +22,8 @@ static void clear_mouse_button(mouse_button* button) {
2422
}
2523

2624
void mouse_set_from_touch(const touch* first, const touch* last) {
25+
auto &data = g_mouse;
26+
2727
data.x = first->current_point.x;
2828
data.y = first->current_point.y;
2929
data.scrolled = touch_get_scroll();
@@ -51,6 +51,8 @@ void mouse_set_from_touch(const touch* first, const touch* last) {
5151
}
5252

5353
void mouse_set_position(int x, int y) {
54+
auto &data = g_mouse;
55+
5456
if (x != data.x || y != data.y)
5557
last_click = 0;
5658

@@ -61,6 +63,8 @@ void mouse_set_position(int x, int y) {
6163
}
6264

6365
void mouse_set_left_down(int down) {
66+
auto &data = g_mouse;
67+
6468
data.left.system_change |= down ? SYSTEM_DOWN : SYSTEM_UP;
6569
data.is_touch = 0;
6670
data.is_inside_window = 1;
@@ -72,20 +76,26 @@ void mouse_set_left_down(int down) {
7276
}
7377

7478
void mouse_set_middle_down(int down) {
79+
auto &data = g_mouse;
80+
7581
data.middle.system_change |= down ? SYSTEM_DOWN : SYSTEM_UP;
7682
data.is_touch = 0;
7783
data.is_inside_window = 1;
7884
last_click = 0;
7985
}
8086

8187
void mouse_set_right_down(int down) {
88+
auto &data = g_mouse;
89+
8290
data.right.system_change |= down ? SYSTEM_DOWN : SYSTEM_UP;
8391
data.is_touch = 0;
8492
data.is_inside_window = 1;
8593
last_click = 0;
8694
}
8795

8896
void mouse_set_inside_window(int inside) {
97+
auto &data = g_mouse;
98+
8999
data.is_inside_window = inside;
90100
data.is_touch = 0;
91101
}
@@ -99,28 +109,38 @@ static void update_button_state(mouse_button* button) {
99109
}
100110

101111
void mouse_determine_button_state() {
112+
auto &data = g_mouse;
113+
102114
update_button_state(&data.left);
103115
update_button_state(&data.middle);
104116
update_button_state(&data.right);
105117
}
106118

107119
void mouse_set_scroll(int state) {
120+
auto &data = g_mouse;
121+
108122
data.scrolled = state;
109123
data.is_touch = 0;
110124
data.is_inside_window = 1;
111125
}
112126

113-
void mouse_reset_scroll(void) {
127+
void mouse_reset_scroll() {
128+
auto &data = g_mouse;
129+
114130
data.scrolled = SCROLL_NONE;
115131
}
116132

117-
void mouse_reset_up_state(void) {
133+
void mouse_reset_up_state() {
134+
auto &data = g_mouse;
135+
118136
data.left.went_up = 0;
119137
data.middle.went_up = 0;
120138
data.right.went_up = 0;
121139
}
122140

123141
void mouse_reset_button_state(void) {
142+
auto &data = g_mouse;
143+
124144
last_click = 0;
125145
clear_mouse_button(&data.left);
126146
clear_mouse_button(&data.middle);

src/platform/mouse.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void system_mouse_set_relative_mode(int enabled) {
2020
auto &data = g_mouse_data;
2121
if (enabled == data.enabled)
2222
return;
23+
2324
if (enabled) {
2425
SDL_GetMouseState(&data.x, &data.y);
2526
SDL_SetRelativeMouseMode(SDL_TRUE);

src/window/window_building_info.cpp

+28-21
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,8 @@ struct building_info_data {
8181
int image_button_id = 0;
8282
int generic_button_id = 0;
8383
int debug_path_button_id = 0;
84-
int overlay_button_id = 0;
8584

86-
generic_button generic_button_layer[1] = {
87-
{375, 3, 24, 24, button_overlay, button_none, 0, 0}
88-
};
85+
std::vector<generic_button> btns;
8986

9087
generic_button generic_button_figures[1] = {
9188
{400, 3, 24, 24, button_debugpath, button_none, 0, 0}
@@ -579,12 +576,18 @@ static void draw_mothball_button(int x, int y, int focused) {
579576
}
580577
}
581578

582-
static void draw_overlay_button(int x, int y, int focused) {
579+
template<class Func>
580+
static void make_button(pcstr label, vec2i pos, vec2i size, Func func) {
583581
auto &context = g_building_info_context;
584-
button_border_draw(x, y, 20, 20, focused ? 1 : 0);
582+
auto &data = g_building_info;
583+
584+
data.btns.push_back({pos.x, pos.y, size.x + 4, size.y + 4, button_none, button_none, 0, 0, func});
585+
int focused = is_button_hover(data.btns.back(), context.offset);
586+
587+
button_border_draw(context.offset.x + pos.x, context.offset.y + pos.y, size.x, size.y, focused ? 1 : 0);
585588

586589
if (context.show_overlay != OVERLAY_NONE) {
587-
text_draw_centered((uint8_t *)(game_state_overlay() != context.show_overlay ? "V" : "v"), x + 1, y + 4, 20, FONT_NORMAL_BLACK_ON_LIGHT, 0);
590+
text_draw_centered((uint8_t *)label, context.offset.x + pos.x + 1, context.offset.y + pos.y + 4, 20, FONT_NORMAL_BLACK_ON_LIGHT, 0);
588591
}
589592
}
590593

@@ -770,6 +773,10 @@ static void draw_background() {
770773

771774
static void draw_foreground() {
772775
auto &context = g_building_info_context;
776+
auto &data = g_building_info;
777+
778+
data.btns.clear();
779+
773780
// building-specific buttons
774781
if (context.type == BUILDING_INFO_BUILDING) {
775782
building *b = building_get(context.building_id);
@@ -852,8 +859,17 @@ static void draw_foreground() {
852859
}
853860

854861
if (context.show_overlay != OVERLAY_NONE) {
855-
draw_overlay_button(context.offset.x + 375, context.offset.y + 3 + 16 * context.height_blocks - 40, g_building_info.overlay_button_id);
862+
pcstr label = (game_state_overlay() != context.show_overlay ? "v" : "V");
863+
make_button(label, {375, 3 + 16 * context.height_blocks - 40}, {20, 20}, [&context] (int, int) {
864+
if (game_state_overlay() != context.show_overlay) {
865+
game_state_set_overlay((e_overlay)context.show_overlay);
866+
} else {
867+
game_state_reset_overlay();
868+
}
869+
window_invalidate();
870+
});
856871
}
872+
857873
}
858874

859875
static int handle_specific_building_info_mouse(const mouse *m) {
@@ -917,6 +933,8 @@ static int handle_specific_building_info_mouse(const mouse *m) {
917933

918934
static void handle_input(const mouse* m, const hotkeys* h) {
919935
auto &context = g_building_info_context;
936+
auto &data = g_building_info;
937+
920938
bool button_id = 0;
921939
int tmp_btn_id;
922940
// general buttons
@@ -951,9 +969,8 @@ static void handle_input(const mouse* m, const hotkeys* h) {
951969
g_building_info.generic_button_figures, g_building_info.debug_path_button_id);
952970
}
953971

954-
if (context.show_overlay != OVERLAY_NONE) {
955-
button_id |= generic_buttons_handle_mouse(m, context.offset + vec2i(0, 16 * context.height_blocks - 40), g_building_info.generic_button_layer, g_building_info.overlay_button_id);
956-
}
972+
int tmp_btn;
973+
button_id |= generic_buttons_handle_mouse(m, context.offset, data.btns, tmp_btn);
957974

958975
if (!button_id && input_go_back_requested(m, h)) {
959976
if (context.storage_show_special_orders) {
@@ -1006,16 +1023,6 @@ static void button_debugpath(int debug, int param2) {
10061023
window_invalidate();
10071024
}
10081025

1009-
static void button_overlay(int debug, int param2) {
1010-
auto &context = g_building_info_context;
1011-
if (game_state_overlay() != context.show_overlay) {
1012-
game_state_set_overlay((e_overlay)context.show_overlay);
1013-
} else {
1014-
game_state_reset_overlay();
1015-
}
1016-
window_invalidate();
1017-
}
1018-
10191026
void window_building_info_show(const map_point& point) {
10201027
window_type window = {
10211028
WINDOW_BUILDING_INFO,

0 commit comments

Comments
 (0)