mirror of
https://github.com/godotengine/godot.git
synced 2024-11-29 07:32:20 +00:00
Many fixes to gradient editor, which was pretty broken. Closes #19308
This commit is contained in:
parent
f1e5b7cf42
commit
6ce9951d9e
@ -29,8 +29,11 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "gradient_edit.h"
|
||||
#include "editor/editor_scale.h"
|
||||
#include "os/keyboard.h"
|
||||
|
||||
#define SPACING (3 * EDSCALE)
|
||||
|
||||
GradientEdit::GradientEdit() {
|
||||
grabbed = -1;
|
||||
grabbing = false;
|
||||
@ -49,11 +52,15 @@ GradientEdit::GradientEdit() {
|
||||
|
||||
int GradientEdit::_get_point_from_pos(int x) {
|
||||
int result = -1;
|
||||
int total_w = get_size().width - get_size().height - 3;
|
||||
int total_w = get_size().width - get_size().height - SPACING;
|
||||
float min_distance = 1e20;
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
//Check if we clicked at point
|
||||
if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) {
|
||||
float distance = ABS(x - points[i].offset * total_w);
|
||||
float min = (POINT_WIDTH / 2 * 1.7); //make it easier to grab
|
||||
if (distance <= min && distance < min_distance) {
|
||||
result = i;
|
||||
min_distance = distance;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -63,7 +70,16 @@ void GradientEdit::_show_color_picker() {
|
||||
if (grabbed == -1)
|
||||
return;
|
||||
picker->set_pick_color(points[grabbed].color);
|
||||
popup->set_position(get_global_position() - popup->get_combined_minimum_size());
|
||||
Size2 minsize = popup->get_combined_minimum_size();
|
||||
bool show_above = false;
|
||||
if (get_global_position().y + get_size().y + minsize.y > get_viewport_rect().size.y) {
|
||||
show_above = true;
|
||||
}
|
||||
if (show_above) {
|
||||
popup->set_position(get_global_position() - Vector2(0, minsize.y));
|
||||
} else {
|
||||
popup->set_position(get_global_position() + Vector2(0, get_size().y));
|
||||
}
|
||||
popup->popup();
|
||||
}
|
||||
|
||||
@ -112,7 +128,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
|
||||
grabbed = _get_point_from_pos(x);
|
||||
|
||||
if (grabbed != -1) {
|
||||
int total_w = get_size().width - get_size().height - 3;
|
||||
int total_w = get_size().width - get_size().height - SPACING;
|
||||
Gradient::Point newPoint = points[grabbed];
|
||||
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
|
||||
|
||||
@ -130,14 +146,15 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
}
|
||||
|
||||
//select
|
||||
if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
|
||||
|
||||
update();
|
||||
int x = mb->get_position().x;
|
||||
int total_w = get_size().width - get_size().height - 3;
|
||||
int total_w = get_size().width - get_size().height - SPACING;
|
||||
|
||||
//Check if color selector was clicked.
|
||||
if (x > total_w + 3) {
|
||||
if (x > total_w + SPACING) {
|
||||
_show_color_picker();
|
||||
return;
|
||||
}
|
||||
@ -211,7 +228,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
|
||||
|
||||
if (mm.is_valid() && grabbing) {
|
||||
|
||||
int total_w = get_size().width - get_size().height - 3;
|
||||
int total_w = get_size().width - get_size().height - SPACING;
|
||||
|
||||
int x = mm->get_position().x;
|
||||
|
||||
@ -286,7 +303,7 @@ void GradientEdit::_notification(int p_what) {
|
||||
if (w == 0 || h == 0)
|
||||
return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
|
||||
|
||||
int total_w = get_size().width - get_size().height - 3;
|
||||
int total_w = get_size().width - get_size().height - SPACING;
|
||||
|
||||
//Draw checker pattern for ramp
|
||||
_draw_checker(0, 0, total_w, h);
|
||||
@ -335,27 +352,36 @@ void GradientEdit::_notification(int p_what) {
|
||||
//Draw point markers
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
|
||||
Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted();
|
||||
Color col = points[i].color.contrasted();
|
||||
col.a = 0.9;
|
||||
|
||||
draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col);
|
||||
draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4));
|
||||
draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col);
|
||||
draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
|
||||
draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col);
|
||||
draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
|
||||
Rect2 rect = Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2);
|
||||
draw_rect(rect, points[i].color, true);
|
||||
draw_rect(rect, col, false);
|
||||
if (grabbed == i) {
|
||||
rect = rect.grow(-1);
|
||||
if (has_focus()) {
|
||||
draw_rect(rect, Color(1, 0, 0, 0.9), false);
|
||||
} else {
|
||||
draw_rect(rect, Color(0.6, 0, 0, 0.9), false);
|
||||
}
|
||||
|
||||
rect = rect.grow(-1);
|
||||
draw_rect(rect, col, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Draw "button" for color selector
|
||||
_draw_checker(total_w + 3, 0, h, h);
|
||||
_draw_checker(total_w + SPACING, 0, h, h);
|
||||
if (grabbed != -1) {
|
||||
//Draw with selection color
|
||||
draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color);
|
||||
draw_rect(Rect2(total_w + SPACING, 0, h, h), points[grabbed].color);
|
||||
} else {
|
||||
//if no color selected draw grey color with 'X' on top.
|
||||
draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1));
|
||||
draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6));
|
||||
draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6));
|
||||
draw_rect(Rect2(total_w + SPACING, 0, h, h), Color(0.5, 0.5, 0.5, 1));
|
||||
draw_line(Vector2(total_w + SPACING, 0), Vector2(total_w + SPACING + h, h), Color(1, 1, 1, 0.6));
|
||||
draw_line(Vector2(total_w + SPACING, h), Vector2(total_w + SPACING + h, 0), Color(1, 1, 1, 0.6));
|
||||
}
|
||||
|
||||
//Draw borders around color ramp if in focus
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "scene/resources/color_ramp.h"
|
||||
#include "scene/resources/default_theme/theme_data.h"
|
||||
|
||||
#define POINT_WIDTH 8
|
||||
#define POINT_WIDTH (8 * EDSCALE)
|
||||
|
||||
class GradientEdit : public Control {
|
||||
|
||||
|
@ -234,15 +234,46 @@ String Popup::get_configuration_warning() const {
|
||||
Popup::~Popup() {
|
||||
}
|
||||
|
||||
void PopupPanel::set_child_rect(Control *p_child) {
|
||||
ERR_FAIL_NULL(p_child);
|
||||
Size2 PopupPanel::get_minimum_size() const {
|
||||
|
||||
Ref<StyleBox> p = get_stylebox("panel");
|
||||
p_child->set_anchors_preset(Control::PRESET_WIDE);
|
||||
p_child->set_margin(MARGIN_LEFT, p->get_margin(MARGIN_LEFT));
|
||||
p_child->set_margin(MARGIN_RIGHT, -p->get_margin(MARGIN_RIGHT));
|
||||
p_child->set_margin(MARGIN_TOP, p->get_margin(MARGIN_TOP));
|
||||
p_child->set_margin(MARGIN_BOTTOM, -p->get_margin(MARGIN_BOTTOM));
|
||||
|
||||
Size2 ms;
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
if (c->is_set_as_toplevel())
|
||||
continue;
|
||||
|
||||
Size2 cms = c->get_combined_minimum_size();
|
||||
ms.x = MAX(cms.x, ms.x);
|
||||
ms.y = MAX(cms.y, ms.y);
|
||||
}
|
||||
|
||||
return ms + p->get_minimum_size();
|
||||
}
|
||||
|
||||
void PopupPanel::_update_child_rects() {
|
||||
|
||||
Ref<StyleBox> p = get_stylebox("panel");
|
||||
|
||||
Vector2 cpos(p->get_offset());
|
||||
Vector2 csize(get_size() - p->get_minimum_size());
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
if (c->is_set_as_toplevel())
|
||||
continue;
|
||||
|
||||
c->set_position(cpos);
|
||||
c->set_size(csize);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupPanel::_notification(int p_what) {
|
||||
@ -250,6 +281,12 @@ void PopupPanel::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_DRAW) {
|
||||
|
||||
get_stylebox("panel")->draw(get_canvas_item(), Rect2(Point2(), get_size()));
|
||||
} else if (p_what == NOTIFICATION_READY) {
|
||||
|
||||
_update_child_rects();
|
||||
} else if (p_what == NOTIFICATION_RESIZED) {
|
||||
|
||||
_update_child_rects();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,10 +77,12 @@ class PopupPanel : public Popup {
|
||||
GDCLASS(PopupPanel, Popup);
|
||||
|
||||
protected:
|
||||
void _update_child_rects();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
void set_child_rect(Control *p_child);
|
||||
virtual Size2 get_minimum_size() const;
|
||||
PopupPanel();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user