Add visual feedback when hovering layer checkboxes in the Inspector

This also changes how checkboxes are selected, which makes it possible
to click in the small area between two checkboxes and
still toggle a value successfully (which is arguably less frustrating).

(cherry picked from commit bbc435624f)
This commit is contained in:
Hugo Locurcio 2019-11-24 11:51:53 +01:00 committed by Rémi Verschelde
parent c9a8309e73
commit 6e8b5aff66

View file

@ -610,6 +610,7 @@ public:
Vector<Rect2> flag_rects; Vector<Rect2> flag_rects;
Vector<String> names; Vector<String> names;
Vector<String> tooltips; Vector<String> tooltips;
int hovered_index;
virtual Size2 get_minimum_size() const { virtual Size2 get_minimum_size() const {
Ref<Font> font = get_font("font", "Label"); Ref<Font> font = get_font("font", "Label");
@ -625,57 +626,79 @@ public:
return String(); return String();
} }
void _gui_input(const Ref<InputEvent> &p_ev) { void _gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev; const Ref<InputEventMouseMotion> mm = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
if (mm.is_valid()) {
for (int i = 0; i < flag_rects.size(); i++) { for (int i = 0; i < flag_rects.size(); i++) {
if (flag_rects[i].has_point(mb->get_position())) { if (flag_rects[i].has_point(mm->get_position())) {
//toggle // Used to highlight the hovered flag in the layers grid.
if (value & (1 << i)) { hovered_index = i;
value &= ~(1 << i); update();
} else { break;
value |= (1 << i);
} }
}
}
const Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
// Toggle the flag.
// We base our choice on the hovered flag, so that it always matches the hovered flag.
if (value & (1 << hovered_index)) {
value &= ~(1 << hovered_index);
} else {
value |= (1 << hovered_index);
}
emit_signal("flag_changed", value); emit_signal("flag_changed", value);
update(); update();
} }
} }
}
}
void _notification(int p_what) { void _notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) { switch (p_what) {
case NOTIFICATION_DRAW: {
Rect2 rect; Rect2 rect;
rect.size = get_size(); rect.size = get_size();
flag_rects.clear(); flag_rects.clear();
int bsize = (rect.size.height * 80 / 100) / 2; const int bsize = (rect.size.height * 80 / 100) / 2;
const int h = bsize * 2 + 1;
int h = bsize * 2 + 1; const int vofs = (rect.size.height - h) / 2;
int vofs = (rect.size.height - h) / 2;
Color color = get_color("highlight_color", "Editor"); Color color = get_color("highlight_color", "Editor");
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
Point2 ofs(4, vofs); Point2 ofs(4, vofs);
if (i == 1) if (i == 1)
ofs.y += bsize + 1; ofs.y += bsize + 1;
ofs += rect.position; ofs += rect.position;
for (int j = 0; j < 10; j++) { for (int j = 0; j < 10; j++) {
Point2 o = ofs + Point2(j * (bsize + 1), 0); Point2 o = ofs + Point2(j * (bsize + 1), 0);
if (j >= 5) if (j >= 5)
o.x += 1; o.x += 1;
uint32_t idx = i * 10 + j; const int idx = i * 10 + j;
bool on = value & (1 << idx); const bool on = value & (1 << idx);
Rect2 rect2 = Rect2(o, Size2(bsize, bsize)); Rect2 rect2 = Rect2(o, Size2(bsize, bsize));
color.a = on ? 0.6 : 0.2; color.a = on ? 0.6 : 0.2;
if (idx == hovered_index) {
// Add visual feedback when hovering a flag.
color.a += 0.15;
}
draw_rect(rect2, color); draw_rect(rect2, color);
flag_rects.push_back(rect2); flag_rects.push_back(rect2);
} }
} }
} break;
case NOTIFICATION_MOUSE_EXIT: {
hovered_index = -1;
update();
} break;
default:
break;
} }
} }
@ -692,6 +715,7 @@ public:
EditorPropertyLayersGrid() { EditorPropertyLayersGrid() {
value = 0; value = 0;
hovered_index = -1; // Nothing is hovered.
} }
}; };
void EditorPropertyLayers::_grid_changed(uint32_t p_grid) { void EditorPropertyLayers::_grid_changed(uint32_t p_grid) {
@ -792,7 +816,7 @@ EditorPropertyLayers::EditorPropertyLayers() {
hb->add_child(grid); hb->add_child(grid);
button = memnew(Button); button = memnew(Button);
button->set_toggle_mode(true); button->set_toggle_mode(true);
button->set_text(".."); button->set_text("...");
button->connect("pressed", this, "_button_pressed"); button->connect("pressed", this, "_button_pressed");
hb->add_child(button); hb->add_child(button);
set_bottom_editor(hb); set_bottom_editor(hb);